Tôi đã cố gắng hiểu tại sao Python 3 thực sự tốn nhiều thời gian so với Python 2 trong một số tình huống nhất định, dưới đây là vài trường hợp tôi đã xác minh từ python 3.4 đến python 2.7.Tại sao Python 3 chậm hơn đáng kể so với Python 2?
Lưu ý: Tôi đã trải qua một số câu hỏi như Why is there no xrange function in Python3? và loop in python3 much slower than python2 và Same code slower in Python3 as compared to Python2, nhưng tôi cảm thấy rằng tôi không hiểu lý do thực sự đằng sau vấn đề này.
Tôi đã thử đoạn mã này để chứng tỏ nó là làm cho sự khác biệt:
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
Khi tôi đã cố gắng chạy chương trình này với py3.4 và py2.7 Tôi đã có dưới đây kết quả .
Lưu ý: Các số liệu thống kê này đi qua máy 64 bit
với bộ xử lý 2.6Ghz
và tính thời gian sử dụng time.time()
trong vòng lặp đơn.
Output : Python 3.4
-----------------
2.6392083168029785
0.9724123477935791
Output: Python 2.7
------------------
1.5131521225
0.475143909454
Tôi thực sự không nghĩ rằng đã có những thay đổi áp dụng cho while
hoặc xrange
2,7-3,4, tôi biết range
đã được bắt đầu đóng vai trò như để xrange
trong py3.4 nhưng như tài liệu nói
range()
hiện hoạt động nhưxrange()
được sử dụng để xử lý, ngoại trừ nó hoạt động với các giá trị có kích thước tùy ý. Cái sau không còn tồn tại nữa.
điều này có nghĩa là thay đổi từ xrange
thành range
rất giống với thay đổi tên nhưng làm việc với các giá trị tùy ý.
Tôi cũng đã xác minh mã byte đã được tháo rời.
Dưới đây là các mã byte tháo rời cho chức năng 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
Và dưới đây là mã byte tháo rời cho chức năng 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
Nếu chúng ta so sánh cả các mã byte họ đã sản xuất cùng một mã byte bị tháo rời.
Bây giờ tôi tự hỏi thay đổi từ 2,7 đến 3,4 thực sự gây ra sự thay đổi lớn trong thời gian thực hiện trong đoạn mã đã cho.
đăng mã đầy đủ và phương pháp đo – njzk2
Chạy thao tác này chỉ một lần với toàn bộ thiết lập trình thông dịch * sẽ không cho bạn biết bất kỳ điều gì. Sử dụng 'timeit.timeit()' để chạy thử nghiệm thời gian thay thế. –