Joe*_*ult 2 python arrays numpy
我正在尝试对 numpy 数组进行基准测试,因为当我尝试在脚本中用 numpy 数组替换 python 数组时,结果比预期的要慢。
我知道我错过了一些东西,我希望有人能澄清我的无知。
我创建了两个函数并对它们计时
NUM_ITERATIONS = 1000
def np_array_addition():
np_array = np.array([1, 2])
for x in xrange(NUM_ITERATIONS):
np_array[0] += x
np_array[1] += x
def py_array_addition():
py_array = [1, 2]
for x in xrange(NUM_ITERATIONS):
py_array[0] += x
py_array[1] += x
Run Code Online (Sandbox Code Playgroud)
结果:
np_array_addition: 2.556 seconds
py_array_addition: 0.204 seconds
Run Code Online (Sandbox Code Playgroud)
是什么赋予了?是什么导致了大规模放缓?我想如果我使用静态大小的数组 numpy 至少会具有相同的速度。
谢谢!
numpy 数组访问速度缓慢一直困扰着我,我想“嘿,它们只是内存中的数组,对吗?Cython 应该解决这个问题!”
它做到了。这是我修改后的基准
import numpy as np
cimport numpy as np
ctypedef np.int_t DTYPE_t
NUM_ITERATIONS = 200000
def np_array_assignment():
cdef np.ndarray[DTYPE_t, ndim=1] np_array = np.array([1, 2])
for x in xrange(NUM_ITERATIONS):
np_array[0] += 1
np_array[1] += 1
def py_array_assignment():
py_array = [1, 2]
for x in xrange(NUM_ITERATIONS):
py_array[0] += 1
py_array[1] += 1
Run Code Online (Sandbox Code Playgroud)
我重新定义了np_array以cdef np.ndarray[DTYPE_t, ndim=1]
print(timeit(py_array_assignment, number=3))
# 0.03459
print(timeit(np_array_assignment, number=3))
# 0.00755
Run Code Online (Sandbox Code Playgroud)
那是python函数也被cython优化了。纯python中python函数的时间是
print(timeit(py_array_assignment, number=3))
# 0.12510
Run Code Online (Sandbox Code Playgroud)
17 倍加速。当然,这是一个愚蠢的例子,但我认为这是有教育意义的。
这不是(只是)缓慢的加法,它是元素访问开销,参见示例:
def np_array_assignment():
np_array = np.array([1, 2])
for x in xrange(NUM_ITERATIONS):
np_array[0] = 1
np_array[1] = 1
def py_array_assignment():
py_array = [1, 2]
for x in xrange(NUM_ITERATIONS):
py_array[0] = 1
py_array[1] = 1
timeit np_array_assignment()
10000 loops, best of 3: 178 us per loop
timeit py_array_assignment()
10000 loops, best of 3: 72.5 us per loop
Run Code Online (Sandbox Code Playgroud)
当一次对整个结构执行时,Numpy 对向量(矩阵)的操作速度很快。这种逐个元素的操作很慢。
使用 numpy 函数避免循环,一次对整个数组进行操作,即:
def np_array_addition_good():
np_array = np.array([1, 2])
np_array += np.sum(np.arange(NUM_ITERATIONS))
Run Code Online (Sandbox Code Playgroud)
将您的功能与上述功能进行比较的结果非常具有启发性:
timeit np_array_addition()
1000 loops, best of 3: 1.32 ms per loop
timeit py_array_addition()
10000 loops, best of 3: 101 us per loop
timeit np_array_addition_good()
100000 loops, best of 3: 11 us per loop
Run Code Online (Sandbox Code Playgroud)
但实际上,如果你折叠循环,你可以用纯 python 做同样的事情:
def py_array_addition_good():
py_array = [1, 2]
rangesum = sum(range(NUM_ITERATIONS))
py_array = [x + rangesum for x in py_array]
timeit py_array_addition_good()
100000 loops, best of 3: 11 us per loop
Run Code Online (Sandbox Code Playgroud)
总而言之,通过如此简单的操作,使用 numpy 确实没有任何改进。纯 python 中的优化代码同样有效。
有很多关于它的问题,我建议在那里查看一些好的答案:
| 归档时间: |
|
| 查看次数: |
4787 次 |
| 最近记录: |