Inb*_*ose 10 python python-2.7 python-3.x
当我遇到这个怪癖时,我只是乱搞.我想确保我不疯狂.
以下代码(适用于2.x和3.x):
from timeit import timeit
print ('gen: %s' % timeit('"-".join(str(n) for n in range(1000))', number=10000))
print ('list: %s' % timeit('"-".join([str(n) for n in range(1000)])', number=10000))
Run Code Online (Sandbox Code Playgroud)
在每个版本,同一台机器上运行3次.
注意:我将时间分组在同一行,以节省空间.
在我的Python 2.7.5上:
gen: 2.37875941643, 2.44095773486, 2.41718937347
list: 2.1132466183, 2.12248106441, 2.11737128131
Run Code Online (Sandbox Code Playgroud)
在我的Python 3.3.2上:
gen: 3.8801268438439718, 3.9939604983350185, 4.166233972077624
list: 2.976764740845537, 3.0062614747229555, 3.0734980312273894
Run Code Online (Sandbox Code Playgroud)
我想知道为什么这是....它可能与如何实现字符串有关?
编辑:我没有使用它再次这样做,range()因为它也从2.x略有变化到3.x而是我使用下面的新代码:
from timeit import timeit
print ('gen: %s' % timeit('"-".join(str(n) for n in (1, 2, 3))', number=1000000))
print ('list: %s' % timeit('"-".join([str(n) for n in (1, 2, 3)])', number=1000000))
Run Code Online (Sandbox Code Playgroud)
Python 2.7.5的时间安排:
gen: 2.13911803683, 2.16418448199, 2.13403650485
list: 0.797961223325, 0.767758578433, 0.803272800119
Run Code Online (Sandbox Code Playgroud)
Python 3.3.2的时间安排:
gen: 2.8188347625218486, 2.882846655874985, 3.0317612259663718
list: 1.3590610502957934, 1.4878876089869366, 1.4978070529462615
Run Code Online (Sandbox Code Playgroud)
编辑2:似乎有更多的事情摆脱了计算,所以我尝试把它降到最低限度.
新守则:
from timeit import timeit
print ('gen: %s' % timeit('"".join(n for n in ("1", "2", "3"))', number=1000000))
print ('list: %s' % timeit('"".join([n for n in ("1", "2", "3")])', number=1000000))
Run Code Online (Sandbox Code Playgroud)
时间Python 2.7.5:
gen: 1.47699698704, 1.46120314534, 1.48290697384
list: 0.323474182882, 0.301259632897, 0.323756694047
Run Code Online (Sandbox Code Playgroud)
时间Python 3.3.2:
gen: 1.633002954259608, 1.6049987598860562, 1.6109927662465935
list: 0.5621341113519589, 0.5789849850819431, 0.5619928557696119
Run Code Online (Sandbox Code Playgroud)
区别很明显,2.x更快,3.x更慢.我很好奇为什么......
我还没有在python3.3上工作过.我在下面说的所有这些都是基于观察.
我使用python反汇编程序来跟踪python 3.3和python 2.7.3中的代码.
s = """
''.join([n for n in ('1', '2', '3')])
"""
Run Code Online (Sandbox Code Playgroud)
我发现上传码有变化.
Python 2.7.3
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import dis
>>> from timeit import timeit
>>> s = """
... ''.join([n for n in ('1', '2', '3')])
... """
>>> timeit(s, number=100000)
0.08443676085287867
>>>
>>>
>>> c = compile(s, '<string>', 'exec')
>>> dis.dis(c)
2 0 LOAD_CONST 0 ('')
3 LOAD_ATTR 0 (join)
6 BUILD_LIST 0
9 LOAD_CONST 5 (('1', '2', '3'))
12 GET_ITER
>> 13 FOR_ITER 12 (to 28)
16 STORE_NAME 1 (n)
19 LOAD_NAME 1 (n)
22 LIST_APPEND 2
25 JUMP_ABSOLUTE 13
>> 28 CALL_FUNCTION 1
31 POP_TOP
32 LOAD_CONST 4 (None)
35 RETURN_VALUE
>>>
Run Code Online (Sandbox Code Playgroud)
python 3.3
Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import dis
>>> from timeit import timeit
>>> s = """
... ''.join([n for n in ('1', '2', '3')])
... """
>>> timeit(s, number=100000)
0.13603410021487614
>>>
>>>
>>> c = compile(s, '<string>', 'exec')
>>> dis.dis(c)
2 0 LOAD_CONST 0 ('')
3 LOAD_ATTR 0 (join)
6 LOAD_CONST 1 (<code object <listcomp> at 0x01F70BB
0, file "<string>", line 2>)
9 LOAD_CONST 2 ('<listcomp>')
12 MAKE_FUNCTION 0
15 LOAD_CONST 7 (('1', '2', '3'))
18 GET_ITER
19 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
22 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
25 POP_TOP
26 LOAD_CONST 6 (None)
29 RETURN_VALUE
>>>
Run Code Online (Sandbox Code Playgroud)
从上传代码我得到的是列表理解已经改变所以我检查了两个版本中的列表理解
Python 2.7.3
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>
>>>
>>> import dis
>>> from timeit import timeit
>>> s = """
... [i for i in ('1', '2', '3')]
... """
>>> timeit(s, number=100000)
0.059500395456104374
>>> c = compile(s, '<string>', 'exec')
>>> dis.dis(c)
2 0 BUILD_LIST 0
3 LOAD_CONST 4 (('1', '2', '3'))
6 GET_ITER
>> 7 FOR_ITER 12 (to 22)
10 STORE_NAME 0 (i)
13 LOAD_NAME 0 (i)
16 LIST_APPEND 2
19 JUMP_ABSOLUTE 7
>> 22 POP_TOP
23 LOAD_CONST 3 (None)
26 RETURN_VALUE
>>>
Run Code Online (Sandbox Code Playgroud)
python 3.3
Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>
>>>
>>> import dis
>>> from timeit import timeit
>>> s = """
... [i for i in ('1', '2', '3')]
... """
>>> timeit(s, number=100000)
0.09876976988887567
>>> c = compile(s, '<string>', 'exec')
>>> dis.dis(c)
2 0 LOAD_CONST 0 (<code object <listcomp> at 0x01FF0BB
0, file "<string>", line 2>)
3 LOAD_CONST 1 ('<listcomp>')
6 MAKE_FUNCTION 0
9 LOAD_CONST 6 (('1', '2', '3'))
12 GET_ITER
13 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
16 POP_TOP
17 LOAD_CONST 5 (None)
20 RETURN_VALUE
>>>
Run Code Online (Sandbox Code Playgroud)
我没有使用python3或检查更改.似乎列表理解实现已经改变.在python3.3中有MAKE_FUNCTION和CALL_FUNCTION.(现在在python2.7中调用一个函数代价很高.我不确定在python3.3中调用函数是否仍然代价高昂.如果是这样的话那么可能会增加一些时间.)