第一個代碼是更快,因爲它避免了所有查找request
及其屬性。見字節碼的區別:
In [6]: dis.dis(test_first)
2 0 LOAD_GLOBAL 0 (request)
3 LOAD_ATTR 1 (session)
6 STORE_FAST 0 (session)
3 9 LOAD_CONST 1 (1)
12 LOAD_FAST 0 (session)
15 LOAD_CONST 2 ('v1')
18 STORE_SUBSCR
4 19 LOAD_CONST 3 (2)
22 LOAD_FAST 0 (session)
25 LOAD_CONST 4 ('v2')
28 STORE_SUBSCR
5 29 LOAD_CONST 5 (3)
32 LOAD_FAST 0 (session)
35 LOAD_CONST 4 ('v2')
38 STORE_SUBSCR
6 39 LOAD_FAST 0 (session)
42 LOAD_CONST 2 ('v1')
45 BINARY_SUBSCR
46 LOAD_CONST 1 (1)
49 COMPARE_OP 2 (==)
52 POP_JUMP_IF_FALSE 68
7 55 LOAD_CONST 6 (4)
58 LOAD_FAST 0 (session)
61 LOAD_CONST 7 ('v4')
64 STORE_SUBSCR
65 JUMP_FORWARD 0 (to 68)
>> 68 LOAD_CONST 0 (None)
71 RETURN_VALUE
對戰:
In [7]: dis.dis(test_second)
2 0 LOAD_CONST 1 (1)
3 LOAD_GLOBAL 0 (request)
6 LOAD_ATTR 1 (session)
9 LOAD_CONST 2 ('v1')
12 STORE_SUBSCR
3 13 LOAD_CONST 3 (2)
16 LOAD_GLOBAL 0 (request)
19 LOAD_ATTR 1 (session)
22 LOAD_CONST 4 ('v2')
25 STORE_SUBSCR
4 26 LOAD_CONST 5 (3)
29 LOAD_GLOBAL 0 (request)
32 LOAD_ATTR 1 (session)
35 LOAD_CONST 4 ('v2')
38 STORE_SUBSCR
5 39 LOAD_GLOBAL 0 (request)
42 LOAD_ATTR 1 (session)
45 LOAD_CONST 2 ('v1')
48 BINARY_SUBSCR
49 LOAD_CONST 1 (1)
52 COMPARE_OP 2 (==)
55 POP_JUMP_IF_FALSE 74
6 58 LOAD_CONST 6 (4)
61 LOAD_GLOBAL 0 (request)
64 LOAD_ATTR 1 (session)
67 LOAD_CONST 7 ('v4')
70 STORE_SUBSCR
71 JUMP_FORWARD 0 (to 74)
>> 74 LOAD_CONST 0 (None)
77 RETURN_VALUE
通知所有額外LOAD_GLOBAL
和第二字節碼LOAD_ATTR
和記住,LOAD_FAST
比LOAD_GLOBAL
快多,因爲LOAD_FAST
做一個簡單的數組查找,而LOAD_GLOBAL
必須查找全局字典(它需要計算變量的哈希等)。
第一個版本有一個LOAD_GLOBAL
和一個LOAD_ATTR
。
事實上,如果我們測試其速度:
In [8]: %timeit test_first()
1000000 loops, best of 3: 343 ns per loop
In [9]: %timeit test_second()
1000000 loops, best of 3: 542 ns per loop
第一個是幾乎快一倍。 但是請注意,它們都很快,而且速度可能並不重要。 如果request
是局部變量,速度差異會減少一點。
第二個還有一個缺點:它重複了很多次相同的事情。使代碼變得更大,可讀性更差並且引入錯別字的機會更大。 這是,我相信,只有事情的重要這些片段。 如果您是出於性能原因選擇它們,那絕對是不成熟的優化。
在您的計算機上運行一些測試,timeit!如果這些不是在大循環中運行,我懷疑你會看到任何性能差異。屬性查找在python中有多昂貴? – dm03514