返回新数组和修改传入数组的性能

时间:2014-11-04 23:02:33

标签: python python-2.7 numpy

[Related]

在下面的快照中,我比较了

的速度
  • 通过切片分配修改现有数组
  • 刚刚返回一个新的,修改过的数组

似乎后者更快。为什么会出现这种情况?


编辑:更新了建议,以及使用numpy的矢量化add()的版本,现在是最快的。

enter image description here

2 个答案:

答案 0 :(得分:1)

我对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操作初始化的数组的地址。

答案 1 :(得分:0)

  • 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