【发布时间】:2021-06-21 14:40:08
【问题描述】:
我正在编写一个将转换应用于一组 xyz 坐标的代码。旧的 xyz 坐标保存在数组 fea 中,新的 xyz 坐标分配给 newFea。 npref 是较小的“原始”版本的 fea(也包含 xyz 坐标),W 是定义平移的矩阵。
代码如下:
@njit(cache=True, nogil=True)
def outerLoop(npref, fea, newFea, W):
n = len(W)
for i in range(1000):
aTerms = W[n - 4] + fea[i][0] * W[n - 3] + fea[i][1] * W[n - 2] + fea[i][2] * W[n - 1]
total = zeros((3,))
for j in range(len(npref)):
dist = sqrt(sum(square(npref[j] - fea[i])))
u = square(dist) * sqrt(log(square(dist)))
total += u * W[j]
newFea[i] = total + aTerms
return newFea
目前,我正在调试它,我要去 1000,但实际上这将不得不运行到大约 130 万。我得到了大约 4 秒的运行时间,对于实际应用来说大约需要一个小时,我希望运行时间减少到 1 秒以下,以便完整的代码可以在 15 分钟内运行。
【问题讨论】:
-
你有没有考虑过使用 Python 以外的东西?
-
我正在将程序从 matlab 移到 python 中。 matlab 可以在大约 30 分钟内运行类似的嵌套循环。我会在 java 中看到显着的性能提升吗?
-
次要(但按 1000*npref 缩放):你
square(dist)在内循环中两次。 -
对于这种事情你可能应该使用 numpy。这是一个用于对数组进行数学运算的库。您告诉它对数组执行一项操作,然后在一次函数调用中将其应用于所有元素。它的底层是 C,因此与 Python 相比它非常快。我建议查看 numpy 并尝试一下,然后在需要帮助时回来。抛开这个具体问题不谈,如果您可能经常对许多值进行数学运算,那么很好值得您花时间学习 numpy。
-
如果你真的想大量优化这样的东西,你应该使用低级语言(C/Fortran,类似的东西),它允许你控制数据在内存中的布局方式。然后,您需要组织循环,以便在优化循环中的操作之外,最大限度地减少缓存抖动。但这是你需要挤压多少的问题。
标签: python performance for-loop optimization numba