【问题标题】:Diagnosing and improving computation speed诊断和提高计算速度
【发布时间】:2014-02-06 16:10:55
【问题描述】:

我有一个导入模块geometry 的脚本,这个模块将我的脚本减慢到一个极端的水平。我的脚本会生成一个位图,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

这是 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中)优化它?

【问题讨论】:

  • @VladimirF 抱歉,我在完成之前错误地点击了“帖子”...
  • 您花费大量时间将 python 列表转换为 numpy 数组。有什么方法可以立即将它们构建为 numpy 数组? (对 numpy 不太熟悉,所以我可能说的是我后退的发际线......)
  • 是否有可能从这里删除任何 numpy 并通过 pypy 运行它?
  • @molbdnilo 你是对的,如果他将 for-loop 推到 numpy 级别,它应该会加快很多
  • 您可能会发现line_profiler 提供的输出比cProfile 更有帮助

标签: python c++ performance numpy tetgen


【解决方案1】:

真正的 time-sink 很可能是你在barycentric_coords 中做的矩阵求逆:

    v = np.dot(la.inv(T), np.array(point)-vertices[-1])

请记住,几乎在所有情况下:Don't invert that matrix!

您可以将该行替换为:

v = np.linalg.lstsq(T, np.array(point)-vertices[-1])[0]

使用更快的最小二乘解决方案获得相同的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 2021-12-14
    相关资源
    最近更新 更多