Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python NumPy';s实施到位的运营商,以解释显著的性能增益_Python_Arrays_Numpy - Fatal编程技术网

Python NumPy';s实施到位的运营商,以解释显著的性能增益

Python NumPy';s实施到位的运营商,以解释显著的性能增益,python,arrays,numpy,Python,Arrays,Numpy,我知道,在Python中,就地操作符使用\uuu iadd\uu方法进行就地操作符。对于不可变类型,\uuuuu iadd\uuuuu是使用\uuu add\uuuuuu的一种变通方法,例如,类似于tmp=a+b;a=tmp,但可变类型(如列表)被修改到位,这会导致轻微的速度提升 但是,如果我有一个NumPy数组,在其中修改它包含的不可变类型,例如整数或浮点,那么速度也会有更显著的提升。这是怎么回事?我做了以下一些基准测试示例: import numpy as np def inplace(a

我知道,在Python中,就地操作符使用
\uuu iadd\uu
方法进行就地操作符。对于不可变类型,
\uuuuu iadd\uuuuu
是使用
\uuu add\uuuuuu
的一种变通方法,例如,类似于
tmp=a+b;a=tmp
,但可变类型(如列表)被修改到位,这会导致轻微的速度提升

但是,如果我有一个NumPy数组,在其中修改它包含的不可变类型,例如整数或浮点,那么速度也会有更显著的提升。这是怎么回事?我做了以下一些基准测试示例:

import numpy as np

def inplace(a, b):
    a += b
    return a

def assignment(a, b):
    a = a + b
    return a

int1 = 1
int2 = 1

list1 = [1]
list2 = [1]

npary1 = np.ones((1000,1000))
npary2 = np.ones((1000,1000))

print('Python integers')
%timeit inplace(int1, 1)
%timeit assignment(int2, 1)

print('\nPython lists')
%timeit inplace(list1, [1])
%timeit assignment(list2, [1])

print('\nNumPy Arrays')
%timeit inplace(npary1, 1)
%timeit assignment(npary2, 1)
当我在NumPy数组上使用就地运算符时,我所期望的是Python整数的类似差异,但是结果完全不同:

Python integers
1000000 loops, best of 3: 265 ns per loop
1000000 loops, best of 3: 249 ns per loop

Python lists
1000000 loops, best of 3: 449 ns per loop
1000000 loops, best of 3: 638 ns per loop

NumPy Arrays
100 loops, best of 3: 3.76 ms per loop
100 loops, best of 3: 6.6 ms per loop

每次调用
赋值(npary2,1)
都需要创建一个新的一百万元素数组。考虑分配一个(1000, 1000)形数组需要花费多少时间:

In [21]: %timeit np.ones((1000, 1000))
100 loops, best of 3: 3.84 ms per loop
新临时数组的分配在我的机器上需要大约3.84毫秒,并且数量级正确,可以解释
就地(npary1,1)
分配(nPary2,1)
之间的全部差异:

因此,考虑到分配是一个相对缓慢的过程,就地添加比分配到新阵列要快得多是有道理的


NumPy阵列上的NumPy操作可能很快,但NumPy阵列的创建相对较慢。例如,考虑创建PyPy数组所需的时间要比Python列表要多:

In [14]: %timeit list()
10000000 loops, best of 3: 106 ns per loop

In [15]: %timeit np.array([])
1000000 loops, best of 3: 563 ns per loop
这就是为什么通常最好使用一个大的NumPy数组(分配一次)而不是数千个小的NumPy数组的原因之一

In [14]: %timeit list()
10000000 loops, best of 3: 106 ns per loop

In [15]: %timeit np.array([])
1000000 loops, best of 3: 563 ns per loop