【发布时间】:2015-01-01 00:36:54
【问题描述】:
[Related]
在下面的快照中,我比较了速度
- 通过切片分配修改现有数组
- 只是返回一个新的、修改后的数组
似乎后者更快。为什么会这样?
编辑:更新了建议,以及使用 numpy 的矢量化 add() 的版本,现在是最快的。
【问题讨论】:
标签: python python-2.7 numpy
[Related]
在下面的快照中,我比较了速度
似乎后者更快。为什么会这样?
编辑:更新了建议,以及使用 numpy 的矢量化 add() 的版本,现在是最快的。
【问题讨论】:
标签: python python-2.7 numpy
我对 python/numpy 的内部结构了解不多,但这是我假设正在发生的事情。只看代码,我就觉得finline 比freturn 做了更多的工作,因为finline 拥有freturn 所做的所有语句(x + 1.0)等等。
也许这可以解释发生了什么:
>>> x = np.random.rand(N)
>>> y = np.zeros(N)
>>> super(np.ndarray, y).__repr__()
Out[33]: '<numpy.ndarray object at 0x24c9c80>'
>>> finline(x, y)
>>> y # see that y was modified
Out[35]:
array([ 1.92772158, 1.47729293, 1.96549695, ..., 1.37821499,
1.8672971 , 1.17013856])
>>> super(np.ndarray, y).__repr__()
Out[36]: '<numpy.ndarray object at 0x24c9c80>' # address of y did not change
>>> y = freturn(x)
>>> super(np.ndarray, y).__repr__()
Out[38]: '<numpy.ndarray object at 0x24c9fc0>' # address of y changed
所以本质上,我认为finline 正在做更多的工作,因为它必须遍历 y 的元素并将它们中的每一个初始化为x + 1.0 操作返回的数组。另一方面,y = freturn(x) 可能只是将y 指针的值重新初始化为等于x + 1.0 操作初始化的数组的地址。
【讨论】:
dis.dis() 的输出...
y[:] = x, y += 1.0。它更快吗?
np.add()的版本,现在最快了。
np.add 是要走的路。
x + 1 将创建一个新数组。y[:] = x + 1:新建数组,将所有数据复制到y
y = x + 1:创建一个新数组并将名称y 绑定到这个新数组。 np.add(x, 1, out=y):不要新建数组,这样最快。代码如下:
x = np.zeros(1000000)
y = np.zeros_like(x)
%timeit x + 1
%timeit y[:] = x + 1
%timeit np.add(x, 1, out=y)
输出:
100 loops, best of 3: 4.2 ms per loop
100 loops, best of 3: 6.83 ms per loop
100 loops, best of 3: 2.5 ms per loop
【讨论】: