在我的python
代码中,我需要遍历大约2500万次,我希望尽可能地对其进行优化。循环中的操作非常简单。为了使代码更高效,我使用了numba
模块,这非常有帮助,但如果可能的话,我想进一步优化代码。
下面是一个完整的工作示例:
import numba as nb
import numpy as np
import time
#######create some synthetic data for illustration purpose##################
size=5000
eps = 0.2
theta_c = 0.4
temp = np.ones(size)
neighbour = np.random.randint(size, size=(size, 3))
coschi = np.random.random_sample((size))
theta = np.random.random_sample((size))*np.pi/2
pwr = np.cos(theta)
###################end of dummy data##########################
###################-----main loop------###############
@nb.jit(fastmath=True)
def func(theta, pwr, neighbour, coschi, temp):
for k in range(np.argmax(pwr), 5000*(pwr.size)):
n = k%pwr.size
if (np.abs(theta[n]-np.pi/2.)<np.abs(theta_c)):
adj = neighbour[n,1]
else:
adj = neighbour[n,0]
psi_diff = np.abs(np.arccos(coschi[adj])-np.arccos(coschi[n]))
temp5 = temp[adj]**5;
e_temp = 1.- np.exp(-temp5*psi_diff/np.abs(eps))
temp[n] = temp[adj] + (e_temp)/temp5*(pwr[n] - temp[adj]**4)
return temp
#check time
time1 = time.time()
temp = func(theta, pwr, neighbour, coschi, temp)
print("Took: ", time.time()-time1, " seconds.")
这会占用我机器上的3.49 seconds
。
为了某种模型拟合的目的,我需要运行这段代码数千次,因此,即使是1秒的优化也意味着为我节省了数十个小时。
可以做什么来进一步优化这段代码?
发布于 2019-06-10 14:54:28
Numba真的很棒。但你是绝望的,记住你总是可以write in C (youtube)。在我自己的问题上,通过逐行将numba翻译成C,我的性能比numba提高了30%。
如果您想花费这些精力,我建议将eigen用于向量操作(在编译时知道向量大小)和pybind11,因为它在numpy和eigen之间进行本机转换。当然,将您的主循环保留在Python中。确保使用适当的编译器标志(如-O3
-march=native
、-mtune=native
、-ffast-math
),并尝试不同的编译器(对我来说,gcc
的输出比clang
快2倍,但同事们报告的情况正好相反)。
如果您不了解任何C++,那么更明智的做法可能是只使用纯C语言,不使用任何库(因为这样可以降低复杂性)。但是您将直接处理Python和numpy C API (不是很难,但是有更多的代码,并且您将学习有关Python内部的所有知识)。
https://stackoverflow.com/questions/56519360
复制相似问题