Python 诊断和提高计算速度
我有一个脚本可以导入一个模块Python 诊断和提高计算速度,python,c++,performance,numpy,tetgen,Python,C++,Performance,Numpy,Tetgen,我有一个脚本可以导入一个模块几何体,这个模块将我的脚本速度降低到了一个极限。我的脚本生成一个位图,对于1600万像素,需要100多个小时 这里是有问题的模块: ''' Created on 2 fevr. 2014 @author: gary ''' #module name is: geometry.py import numpy as np import numpy.linalg as la import tetgen def barycentric_coords(vertices,
几何体,这个模块将我的脚本速度降低到了一个极限。我的脚本生成一个位图,对于1600万像素,需要100多个小时
这里是有问题的模块:
'''
Created on 2 fevr. 2014
@author: gary
'''
#module name is: geometry.py
import numpy as np
import numpy.linalg as la
import tetgen
def barycentric_coords(vertices, point):
T = (np.array(vertices[:-1])-vertices[-1]).T
v = np.dot(la.inv(T), np.array(point)-vertices[-1])
v.resize(len(vertices))
v[-1] = 1-v.sum()
#print vertices
return v
def tetgen_of_hull(points):
tg_all = tetgen.TetGen(points)
hull_i = set().union(*tg_all.hull)
hull_points = [points[i] for i in hull_i]
tg_hull = tetgen.TetGen(hull_points)
return tg_hull, hull_i
def containing_tet(tg, point):
for tet in tg.tets:
verts = [tg.points[j] for j in tet]
bcoords = barycentric_coords(verts, point)
if (bcoords >= 0).all():
return bcoords
return None, None
这是我的脚本中使用上述函数的stats cProfile,显然这是花费时间的地方:
ncalls tottime percall cumtime percall filename:lineno(function)
1291716 45.576 0.000 171.672 0.000 geometry.py:10(barycentric_coords)
6460649 31.617 0.000 31.617 0.000 {numpy.core.multiarray.array}
2583432 15.979 0.000 15.979 0.000 {method 'reduce' of 'numpy.ufunc'
objects}
2031 12.032 0.006 193.333 0.095 geometry.py:26(containing_tet)
1291716 10.944 0.000 58.323 0.000 linalg.py:244(solve)
1291716 7.075 0.000 7.075 0.000 {numpy.linalg.lapack_lite.dgesv}
1291716 5.750 0.000 9.865 0.000 linalg.py:99(_commonType)
2583432 5.659 0.000 5.659 0.000 {numpy.core.multiarray._fastCopyAn
dTranspose}
1291716 5.526 0.000 7.299 0.000 twodim_base.py:169(eye)
1291716 5.492 0.000 12.791 0.000 numeric.py:1884(identity)
所以我的问题是:
numpy
在这里处理重心坐标的计算似乎相当慢,在c++
中这样做值得吗?或者是否有其他方法(在python中)对此进行优化?实时接收器很可能是在重心坐标中执行的矩阵求逆:
v = np.dot(la.inv(T), np.array(point)-vertices[-1])
请记住,在几乎所有情况下:
您可以将该行替换为:
v = np.linalg.lstsq(T, np.array(point)-vertices[-1])[0]
用更快的最小二乘法得到同样的结果。@VladimirF抱歉,我在结束之前错误地单击了“post”…您正在花费大量时间将python列表转换为numpy数组。有没有什么方法可以立即将它们构建为numpy阵列?(对numpy不太熟悉,所以我可能是在说我的发丝在后退…)有可能从这里移除任何numpy并通过pypy运行吗?@molbdnilo你是对的,如果他将for循环向下推到numpy级别,它应该会加快LOT的速度,您可能会发现它提供的输出比cProfile