1 python performance list-comprehension python-3.x map-function
鉴于以下测试:
>>> import timeit
>>> timeit.timeit("[x + 'abc' for x in ['x', 'y', 'z']]")
>>> timeit.timeit("map(lambda x: x + 'abc', ['x', 'y', 'z'])")
Run Code Online (Sandbox Code Playgroud)
使用Python 2.7和3.4(Debian 8/testing/jessie),我得到以下数字:
Python27 Python34
1.3s 0.5s map()
0.6s 0.9s list comprehension
Run Code Online (Sandbox Code Playgroud)
使用Python 3显着改善了地图,列表理解受到严重影响.
问题:将代码从Python 2移植到Python 3时,是否建议将列表推导更改为map()?
您没有正确测试.在Python 3中,map()返回一个迭代器,而不是一个列表.您实际上并没有在测试中进行迭代,只测试迭代器的创建.
您需要包含迭代以查看哪种方法更快; 你可以使用collections.deque()长度为0,这将迭代而不产生新的列表对象:
import timeit
timeit.timeit("deque([x + 'abc' for x in ['x', 'y', 'z']], maxlen=0)",
'from collections import deque')
timeit.timeit("deque(map(lambda x: x + 'abc', ['x', 'y', 'z']), maxlen=0)",
'from collections import deque')
Run Code Online (Sandbox Code Playgroud)
通过应用这deque()两个你甚至再次得分.
现在列表推导在两个平台上获胜:
Python27 Python34
1.91s 2.00s map()
1.18s 1.85s list comprehension
Run Code Online (Sandbox Code Playgroud)
您应该使用更大的输入列表来正确测试差异; 太多了
列表理解在Python 3上放慢速度的原因是因为它们有自己的适当范围,就像生成器表达式以及dict和set comprehensions在Python 2和3上都做的那样.
如果你的map函数完全用C实现(而不是lambda,它会推回到Python,map() 可能会获胜:
>>> timeit.timeit("deque([m(i) for i in ['x', 'y', 'z']], maxlen=0)",
... "from collections import deque; from operator import methodcaller; m = methodcaller('__add__', 'abc')")
2.3514049489967874
>>> timeit.timeit("deque(map(methodcaller('__add__', 'abc'), ['x', 'y', 'z']), maxlen=0)",
... 'from collections import deque; from operator import methodcaller')
1.7684289459939464
Run Code Online (Sandbox Code Playgroud)
这里的methodcaller()对象通过调用str.__add__每个使用的对象的方法来避免回调到Python代码.
| 归档时间: |
|
| 查看次数: |
347 次 |
| 最近记录: |