我一直在試圖理解爲什麼Python 3在某些情況下實際上比Python 2花費了很多時間,下面是我已經從python 3.4驗證到python 2.7的一些情況。爲什麼Python 3比Python 2慢得多?
注意:我已經通過了Why is there no xrange function in Python3?和loop in python3 much slower than python2和Same code slower in Python3 as compared to Python2等一些問題,但我覺得我沒有得到這個問題背後的實際原因。
我已經試過這一段代碼來顯示它是如何做的區別:
MAX_NUM = 3*10**7
# This is to make compatible with py3.4.
try:
xrange
except:
xrange = range
def foo():
i = MAX_NUM
while i> 0:
i -= 1
def foo_for():
for i in xrange(MAX_NUM):
pass
當我試圖運行與py3.4和py2.7這個節目,我已經得到了以下 結果。
注意:這些統計信息是通過64 bit
機器和2.6Ghz
處理器計算出來的,並使用time.time()
單循環計算出時間。
Output : Python 3.4
-----------------
2.6392083168029785
0.9724123477935791
Output: Python 2.7
------------------
1.5131521225
0.475143909454
我真的不認爲出現了2.7應用於while
或xrange
到3.4的變化,我知道range
已經開始充當在py3.4 xrange
但文件說,
range()
現在的行爲與xrange()
相似,只是它可以處理任意大小的值。後者不再存在。
這意味着從xrange
更改爲range
非常類似於名稱更改,但使用任意值。
我已驗證反彙編的字節碼。
下面是功能foo()
反彙編的字節碼:
Python 3.4:
---------------
13 0 LOAD_GLOBAL 0 (MAX_NUM)
3 STORE_FAST 0 (i)
14 6 SETUP_LOOP 26 (to 35)
>> 9 LOAD_FAST 0 (i)
12 LOAD_CONST 1 (0)
15 COMPARE_OP 4 (>)
18 POP_JUMP_IF_FALSE 34
15 21 LOAD_FAST 0 (i)
24 LOAD_CONST 2 (1)
27 INPLACE_SUBTRACT
28 STORE_FAST 0 (i)
31 JUMP_ABSOLUTE 9
>> 34 POP_BLOCK
>> 35 LOAD_CONST 0 (None)
38 RETURN_VALUE
python 2.7
-------------
13 0 LOAD_GLOBAL 0 (MAX_NUM)
3 STORE_FAST 0 (i)
14 6 SETUP_LOOP 26 (to 35)
>> 9 LOAD_FAST 0 (i)
12 LOAD_CONST 1 (0)
15 COMPARE_OP 4 (>)
18 POP_JUMP_IF_FALSE 34
15 21 LOAD_FAST 0 (i)
24 LOAD_CONST 2 (1)
27 INPLACE_SUBTRACT
28 STORE_FAST 0 (i)
31 JUMP_ABSOLUTE 9
>> 34 POP_BLOCK
>> 35 LOAD_CONST 0 (None)
38 RETURN_VALUE
而且下面是功能foo_for()
反彙編的字節碼:
Python: 3.4
19 0 SETUP_LOOP 20 (to 23)
3 LOAD_GLOBAL 0 (xrange)
6 LOAD_GLOBAL 1 (MAX_NUM)
9 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
12 GET_ITER
>> 13 FOR_ITER 6 (to 22)
16 STORE_FAST 0 (i)
20 19 JUMP_ABSOLUTE 13
>> 22 POP_BLOCK
>> 23 LOAD_CONST 0 (None)
26 RETURN_VALUE
Python: 2.7
-------------
19 0 SETUP_LOOP 20 (to 23)
3 LOAD_GLOBAL 0 (xrange)
6 LOAD_GLOBAL 1 (MAX_NUM)
9 CALL_FUNCTION 1
12 GET_ITER
>> 13 FOR_ITER 6 (to 22)
16 STORE_FAST 0 (i)
20 19 JUMP_ABSOLUTE 13
>> 22 POP_BLOCK
>> 23 LOAD_CONST 0 (None)
26 RETURN_VALUE
如果我們比較這兩個字節的代碼,他們已經生產相同的反彙編字節碼。
現在我想知道從2.7到3.4的變化是否真的會導致給定代碼片段執行時間的巨大變化。
發佈全部代碼和測量方法 – njzk2
只用一次*整個解釋器設置*就不會告訴你任何東西。使用'timeit.timeit()'來代替運行時間測試。 –