[英]What is the difference between these two (Python) code samples?
我是python初學者。 我想知道...
問題1:sample2是否比sample1更快一點並且內存使用更少? (因為它沒有聲明和分配變量)
問題2:哪個樣本更適合“大型”計划? (即使是大型程序,也有什么區別嗎?)
樣本1:
session = request.session
session['v1'] = 1
session['v2'] = 2
session['v2'] = 3
if session['v1'] == 1:
session['v4'] = 4
示例2:
request.session['v1'] = 1
request.session['v2'] = 2
request.session['v2'] = 3
if request.session['v1'] == 1:
request.session['v4'] = 4
不適合過早的優化。 只是為了知道...
第一個代碼更快,因為它避免了對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
是局部變量,則速度差異會降低一點。
第二個缺點還有另一個缺點:它會重復很多次相同的事情。 使代碼既更大,更易讀,又增加了輸入錯誤的機會。 我認為,這是這些片段中唯一重要的事情。 如果出於性能原因選擇它們:那絕對是過早的優化。
它可能並沒有太大的區別。 第一個解決方案可能無限快。
除了解決方案(都不錯)之外,並假設request.session類似於dict,您還可以考慮:
request.session.update({
'v1': 1,
'v2': 2,
…
})
取決於更改的數量以及新信息是否已經存在。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.