更快地进行循环计算

时间:2021-01-13 19:32:16

标签: python numpy for-loop optimization

我有一个 for 循环对数组的元素执行一些操作。数组中有 1e5 个元素

import numpy as np
A=np.array([1,2,3,4..........100000)]
for i in range(0,len(A)):
       A[i]=(A[i]*2+A[i]*4)**(1/3)

我想在上面的代码中获得并行化,以便 for 循环的每次执行都转到不同的核心,从而使代码执行速度更快。我有一个 48 核的工作站。如何在python中实现这种并行处理?请帮忙。

2 个答案:

答案 0 :(得分:4)

暂时不要打扰并行化。现在,您没有利用numpy矢量化;您也可以使用 Python list(或者 array.array)来获得 numpy 给您的所有好处。

实际使用矢量化功能,开销应该下降几个数量级:

import numpy as np
A = np.array([1,2,3,4..........100000])  # If this is actually the values you want, use np.arange(1, 100000+1) to speed it up
A = (A * 6) ** (1 / 3)

# If the result should truncate back to int64, not convert to doubles, cast back at the end
A = A.astype(np.int64)

(A * 6) ** (1 / 3) 执行与 for 循环相同的工作,但更快(您可以将原始代码与 A = (A * 2 + A * 4) ** (1/3) 更紧密地匹配,但乘以将 24 分开并将它们加在一起当您可以直接乘以 6 时毫无意义)。最后一行(可选,取决于意图)通过截断回原始整数 dtype 获得与原始循环完全等效的行为。

将性能与微基准测试的 ipython %%timeit 魔法进行比较:

In [2]: %%timeit
   ...: A = np.arange(1, 100000+1)
   ...: for i in range(len(A)):
   ...:     A[i] = (A[i]*2 + A[i]*4) ** (1/3)
   ...:
427 ms ± 6.49 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [3]: %%timeit
   ...: A = np.arange(1, 100000+1)
   ...: A = (A * 6) ** (1/3)
   ...:
2.72 ms ± 51 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

向量化代码占用的时间大约是 naive 循环的 0.6%;仅仅并行化朴素循环永远不会接近实现那种加速。添加 .astype(np.int64) 转换只会将运行时间增加约 6%,仍然是原始 for 循环所需的微不足道的一小部分。

答案 1 :(得分:0)

让 numpy 来做艰苦的工作。

A = (A*2+A*4)**(1/3)
相关问题