Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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
Performance 加速结构化NumPy阵列_Performance_Python 3.x_Numpy - Fatal编程技术网

Performance 加速结构化NumPy阵列

Performance 加速结构化NumPy阵列,performance,python-3.x,numpy,Performance,Python 3.x,Numpy,NumPy数组在性能和易用性方面都非常出色(比列表更易于切片和索引) 我尝试用NumPy结构化数组构建数据容器,而不是NumPy数组的dict。问题是性能要差得多。使用同质数据大约是2.5倍,使用异构数据大约是32倍(我说的是NumPydatatypes) 有没有办法加快结构化阵列的速度?我尝试将memoryorder从“c”更改为“f”,但没有任何效果 以下是我的分析代码: import time import numpy as np NP_SIZE = 100000 N_REP = 100

NumPy
数组在性能和易用性方面都非常出色(比列表更易于切片和索引)

我尝试用
NumPy结构化数组构建数据容器,而不是
NumPy数组的
dict
。问题是性能要差得多。使用同质数据大约是2.5倍,使用异构数据大约是32倍(我说的是
NumPy
datatypes)

有没有办法加快结构化阵列的速度?我尝试将memoryorder从“c”更改为“f”,但没有任何效果

以下是我的分析代码:

import time
import numpy as np

NP_SIZE = 100000
N_REP = 100

np_homo = np.zeros(NP_SIZE, dtype=[('a', np.double), ('b', np.double)], order='c')
np_hetro = np.zeros(NP_SIZE, dtype=[('a', np.double), ('b', np.int32)], order='c')
dict_homo = {'a': np.zeros(NP_SIZE), 'b': np.zeros(NP_SIZE)}
dict_hetro = {'a': np.zeros(NP_SIZE), 'b': np.zeros(NP_SIZE, np.int32)}

t0 = time.time()
for i in range(N_REP):
    np_homo['a'] += i

t1 = time.time()
for i in range(N_REP):
    np_hetro['a'] += i

t2 = time.time()
for i in range(N_REP):
    dict_homo['a'] += i

t3 = time.time()
for i in range(N_REP):
    dict_hetro['a'] += i
t4 = time.time()

print('Homogeneous Numpy struct array took {:.4f}s'.format(t1 - t0))
print('Hetoregeneous Numpy struct array took {:.4f}s'.format(t2 - t1))
print('Homogeneous Dict of numpy arrays took {:.4f}s'.format(t3 - t2))
print('Hetoregeneous Dict of numpy arrays took {:.4f}s'.format(t4 - t3))
编辑:忘记输入计时号码:

Homogenious Numpy struct array took 0.0101s
Hetoregenious Numpy struct array took 0.1367s
Homogenious Dict of numpy arrays took 0.0042s
Hetoregenious Dict of numpy arrays took 0.0042s
Edit2:我在timit模块中添加了一些额外的测试用例:

import numpy as np
import timeit

NP_SIZE = 1000000

def time(data, txt, n_rep=1000):
    def intern():
        data['a'] += 1

    time = timeit.timeit(intern, number=n_rep)
    print('{} {:.4f}'.format(txt, time))


np_homo = np.zeros(NP_SIZE, dtype=[('a', np.double), ('b', np.double)], order='c')
np_hetro = np.zeros(NP_SIZE, dtype=[('a', np.double), ('b', np.int32)], order='c')
dict_homo = {'a': np.zeros(NP_SIZE), 'b': np.zeros(NP_SIZE)}
dict_hetro = {'a': np.zeros(NP_SIZE), 'b': np.zeros(NP_SIZE, np.int32)}

time(np_homo, 'Homogeneous Numpy struct array')
time(np_hetro, 'Hetoregeneous Numpy struct array')
time(dict_homo, 'Homogeneous Dict of numpy arrays')
time(dict_hetro, 'Hetoregeneous Dict of numpy arrays')
结果:

Homogeneous Numpy struct array 0.7989
Hetoregeneous Numpy struct array 13.5253
Homogeneous Dict of numpy arrays 0.3750
Hetoregeneous Dict of numpy arrays 0.3744
两次运行之间的比率似乎相当稳定。使用两种方法和不同大小的数组

对于offcase,它很重要: python:3.4
NumPy:1.9.2

在我的快速计时测试中,差异并没有那么大:

In [717]: dict_homo = {'a': np.zeros(10000), 'b': np.zeros(10000)}
In [718]: timeit dict_homo['a']+=1
10000 loops, best of 3: 25.9 µs per loop
In [719]: np_homo = np.zeros(10000, dtype=[('a', np.double), ('b', np.double)])
In [720]: timeit np_homo['a'] += 1
10000 loops, best of 3: 29.3 µs per loop
在dict_homo
案例中,数组嵌入到字典中这一事实是次要的。这样简单的字典访问速度很快,基本上与通过变量名访问数组相同

因此,第一种情况基本上是对1d阵列进行
+=
测试

在结构化情况下,
a
b
值在数据缓冲区中交替,因此
np_homo['a']
是一个“提取”替代数字的视图。所以它会稍微慢一点也不奇怪

In [721]: np_homo
Out[721]: 
array([(41111.0, 0.0), (41111.0, 0.0), (41111.0, 0.0), ..., (41111.0, 0.0),
       (41111.0, 0.0), (41111.0, 0.0)], 
      dtype=[('a', '<f8'), ('b', '<f8')])
令人惊讶的是,它实际上比结构化案例慢了一点。使用
order='F'
或(210000)shape可以稍微加快速度,但仍然不如结构化案例那么好

这些都是很小的测试时间,所以我不会提出太大的要求。但结构化阵列不会回头看


另一次测试,在每一步初始化数组或字典

In [730]: %%timeit np.twod=np.zeros((10000,2), np.double)
np.twod[:,0] += 1
   .....: 
10000 loops, best of 3: 36.7 µs per loop
In [731]: %%timeit np_homo = np.zeros(10000, dtype=[('a', np.double), ('b', np.double)])
np_homo['a'] += 1
   .....: 
10000 loops, best of 3: 38.3 µs per loop
In [732]: %%timeit dict_homo = {'a': np.zeros(10000), 'b': np.zeros(10000)}
dict_homo['a'] += 1
   .....: 
10000 loops, best of 3: 25.4 µs per loop

2d和structured更接近,对于dictionary(1d)的情况来说性能更好。我也尝试了
np.one
,因为
np.zero
可以延迟分配,但在行为上没有区别。

因为这个问题询问的是NumPy的具体性能问题,而不是一般性的批评,它已经从代码审查迁移到堆栈溢出。如果您真的想使用结构化数组,我建议您尝试一下。请看这个问题:我在这里看到了相同的计时。至于
np\u homo
vs.
np\u hetero
,可能与对齐有关,因为作为第二个数据类型的
np.int64
并不慢。@MaxNoe。在我开始这个问题之前我看到了。然而,我相信这不是同一件事,因为我使用1.9.2,而问题在1.10Hmm中刚刚出现。那很有趣。特别是第一个结果。您是否尝试增加元素的大小?只是为了确保所需的时间不受某个常数的支配。
In [730]: %%timeit np.twod=np.zeros((10000,2), np.double)
np.twod[:,0] += 1
   .....: 
10000 loops, best of 3: 36.7 µs per loop
In [731]: %%timeit np_homo = np.zeros(10000, dtype=[('a', np.double), ('b', np.double)])
np_homo['a'] += 1
   .....: 
10000 loops, best of 3: 38.3 µs per loop
In [732]: %%timeit dict_homo = {'a': np.zeros(10000), 'b': np.zeros(10000)}
dict_homo['a'] += 1
   .....: 
10000 loops, best of 3: 25.4 µs per loop