【发布时间】:2020-07-10 06:29:20
【问题描述】:
我有这个代码:
output_array = np.vectorize(f, otypes='d')(input_array)
我想用这段代码替换它,它应该给出相同的输出:
output_array = np.ndarray(input_array.shape, dtype='d')
for i, item in enumerate(input_array):
output_array[i] = f(item)
我想要第二个版本的原因是我可以在计算时在单独的线程中开始迭代 output_array。 (是的,我知道 GIL,这部分已经处理好了。)
不幸的是,for 循环非常慢,即使我没有在单独的线程上处理数据。我在我的目标平台 CPython 和 PyPy3 上对它进行了基准测试。在 CPython 上它比 vectorize 慢 3 倍,在 PyPy3 上它比 vectorize 慢 67 倍!
尽管 Numpy 文档说“提供vectorize 函数主要是为了方便,而不是为了性能。实现本质上是一个 for 循环。”
知道为什么我的实现很慢,以及如何快速实现仍然允许我在完成之前使用output_array?
【问题讨论】:
-
首先,不要使用
np.ndarray。用np.zeros或np.empty初始化一个数组。但话虽如此,我很惊讶np.vectorize更快。告诉我们一些关于函数的事情。还有input_array- 什么是dtype和shape(大致)。 -
我不确定它的相关性如何,但它基本上做了一堆
math.sin动作、乘法和指数。这里是get_pressure方法:github.com/cool-RR/python_synthesizer/blob/master/… -
您能否将
math.sin(等)替换为np.sin并跳过vectorize和循环? -
我考虑过这一点,但我必须改变我的程序的整个构建方式,如果可能的话,我想避免这种情况。