列表理解,映射和numpy.vectorize性能
我有一个函数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的速度要比CPython快。
:-)
就listcomps与
map()
调用而言…一个调用101个函数,而另一个调用102个。这意味着您不会看到时间上的显着差异,如下所示,使用@Mike建议的 timeit
模块:- 清单理解
$ 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
尽管如此,除非您打算 使用
通过这两种技术创建的列表,否则请完全避免使用它们(使用列表)。IOW,如果您要做的只是遍历它们,那么当您只关心一次查看每个元素时,只要立即丢弃该列表,就不值得消耗内存(并可能在内存中创建潜在的庞大列表)。你完成了。在这种情况下,我强烈建议您使用 生成器表达式,
因为它们不会在内存中创建整个列表…这是一种更友好的内存,懒惰的迭代方式,可以循环遍历元素以处理不创建大型函数内存中的数组。最好的部分是它的语法与listcomps的语法几乎相同:a = (foo(i) for i in range(100))
仅限2.x用户
:沿着更多的迭代路线,将任何旧版2.x代码的所有range()
调用都更改为xrange()
,然后range()
在移植到Python
3xrange()
替换并重命名为时切换到range()
。