我有一个函数foo(i),它需要一个整数,并且要花费大量时间才能执行。以下初始化a的任何方法之间是否会存在明显的性能差异:
a = [foo(i) for i in xrange(100)]
a = map(foo, range(100))
vfoo = numpy.vectorize(foo)
a = vfoo(range(100))
(我不在乎输出是列表还是numpy数组。)
还有更好的方法吗?
[第一条评论:不要在样品中混合使用xrange(
)或range()
...这样做会使您的问题在您比较苹果和橙子时失效。
我第二个@Gabe的想法是,如果您具有许多大型数据结构,则numpy应该赢得整体...只是要记住,大多数时候C的速度要比Python快,但是大多数时候PyPy的速度要比Python快。 CPython。 :-)
就listcomps与map()
调用而言...一个进行101个函数调用,而另一个进行102个函数调用。这意味着您不会在时间上有明显的不同,如下所示,使用timeit 模块,因为@Mike建议:
列表理解
$ python -m timeit "def foo(x):pass; [foo(i) for i in range(100)]"
1000000 loops, best of 3: 0.216 usec per loop
$ python -m timeit "def foo(x):pass; [foo(i) for i in range(100)]"
1000000 loops, best of 3: 0.21 usec per loop
$ python -m timeit "def foo(x):pass; [foo(i) for i in range(100)]"
1000000 loops, best of 3: 0.212 usec per loop
[map()
函数调用
$ python -m timeit "def foo(x):pass; map(foo, range(100))"
1000000 loops, best of 3: 0.216 usec per loop
$ python -m timeit "def foo(x):pass; map(foo, range(100))"
1000000 loops, best of 3: 0.214 usec per loop
$ python -m timeit "def foo(x):pass; map(foo, range(100))"
1000000 loops, best of 3: 0.215 usec per loop
尽管如此,除非您打算在using中计划使用这两种技术创建的列表,否则请尝试完全避免使用它们(使用列表)。 IOW,如果您要做的只是遍历它们,那么当您只关心一次查看每个元素时,只要丢弃该列表,就不值得消耗内存(并可能在内存中创建潜在的庞大列表)。完成了。
在这种情况下,我强烈建议使用generator表达式,因为它们不会在内存中创建整个列表...这是一种更友好的内存,通过元素循环进行处理的惰性迭代方式没有在内存中创建大型数组。最好的部分是它的语法几乎与listcomps相同:
a = (foo(i) for i in range(100))
仅[2.x用户]]:沿着更多的迭代路线,将任何较旧的2.x代码的所有range()
调用都更改为xrange()
,然后在移植到Python 3时切换到range()
,其中[ C0]替换并重命名为xrange()
。
您为什么要对此进行优化?您是否编写了经过测试的有效代码,然后检查了算法range()
,并发现优化此方法会产生效果?您是否在一个深层的内循环中这样做,发现自己在浪费时间?如果没有,请不要打扰。