【发布时间】:2016-11-11 17:51:41
【问题描述】:
考虑在 python 3 下对 Ipython 进行性能测试:
创建一个范围、一个 range_iterator 和一个生成器
In [1]: g1 = range(1000000)
In [2]: g2 = iter(range(1000000))
In [3]: g3 = (i for i in range(1000000))
使用 python 原生 sum 测量求和时间
In [4]: %timeit sum(g1)
10 loops, best of 3: 47.4 ms per loop
In [5]: %timeit sum(g2)
The slowest run took 374430.34 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 123 ns per loop
In [6]: %timeit sum(g3)
The slowest run took 1302907.54 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 128 ns per loop
不确定我是否应该担心这个警告。 range 版本时序变化很大(为什么?),但是 range_iterator 和生成器是相似的。
现在让我们使用 numpy.sum
In [7]: import numpy as np
In [8]: %timeit np.sum(g1)
10 loops, best of 3: 174 ms per loop
In [9]: %timeit np.sum(g2)
The slowest run took 8.47 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 6.51 µs per loop
In [10]: %timeit np.sum(g3)
The slowest run took 9.59 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 446 ns per loop
g1 和 g3 变慢了 x~3.5,但 range_iterator g2 现在比原生总和慢了约 50 倍。 g3 获胜。
In [11]: type(g1)
Out[11]: range
In [12]: type(g2)
Out[12]: range_iterator
In [13]: type(g3)
Out[13]: generator
为什么对 numpy.sum 上的 range_iterator 有这样的惩罚?应该避免此类物体吗?它是否泛化 - “自制”生成器是否总是在 numpy 上击败其他对象?
编辑 1: 我意识到 np.sum 不评估 range_iterator 而是返回另一个 range_iterator 对象。所以这个比较不好。为什么不进行评估?
编辑 2: 我还意识到 numpy.sum 将范围保持为整数形式,因此由于整数溢出而在我的总和上给出了错误的结果。
In [12]: sum(range(1000000))
Out[12]: 499999500000
In [13]: np.sum(range(1000000))
Out[13]: 1783293664
In [14]: np.sum(range(1000000), dtype=float)
Out[14]: 499999500000.0
中间结论 - 不要在非 numpy 对象上使用 numpy.sum...?
【问题讨论】:
-
这是在重申之前被标记为离题的类似问题。希望你能找到这个主题。
-
@SSDMS - 答案是给
import array,而不是import numpy。 -
由于你使用的是Ipython,所以使用
np.sum??查看它的代码。除了generator(不是迭代器)的特殊情况,np.sum对输入的np.array版本进行操作。因此,如果np.sum的行为让您感到困惑,请查看np.array(arg)。
标签: python python-3.x numpy ipython