【发布时间】:2020-09-18 17:59:07
【问题描述】:
我正在研究基于稀疏体素八叉树的 STL 模型的体素化。 我有一个包含大约 100,000 个三角形的 3D 数组(每个三角形有 3 个点,每个点都有 x、y、z 值)。
我需要为每个三角形计算一些点和值。 我用标准 CPython 编写了这个算法,运行了 3 秒,这对我来说太慢了(大约 0.5 秒就好了)。
我切换到 PyPy 作为 JIT 编译器,它的表现非常好。 如果我为每个三角形(计算边界框和法线)运行没有点/值集 A 的代码(请参阅代码),它的性能优于 CPython 10 倍或更多,如果我运行没有点集 B 的代码,它的性能优于 CPython好吧。当我用两组运行算法时,它的运行速度比 CPYthon(或 Set A solo + Set B solo 组合)慢得多。
您知道问题出在哪里吗? 我想可能是内存有问题。我在 vm 选项中为 pypy 分配了更多堆内存,但没有用。我在循环迭代后删除了所有变量(使用“del”)不起作用。
我在基于 x64 的机器上使用 Windows 10 Home 版本 10.0.18363。
我在 PyCharm Community Edition 2020.2.2 中使用 pypy3.6-v7.3.2rc1-win32
这些是虚拟机选项:
-Xmx2048m
-Xms750m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-XX:CICompilerCount=2
-Dsun.io.useCanonPrefixCache=false
-Djdk.http.auth.tunneling.disabledSchemes=""
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Djdk.attach.allowAttachSelf=true
-Dkotlinx.coroutines.debug=off
-Djdk.module.illegalAccess.silent=true
非常感谢您的每一个建议。
import trimesh as tr
import sys
import datetime
def doT(a,b):
res=a[0]*b[0]+a[1]*b[1]+a[2]*b[2]
return res
def doT2(a,b):
res=a[0]*b[0]+a[1]*b[1]
return res
def minus (a,b):
res=[a[0]-b[0],a[1]-b[1],a[2]-b[2]]
return res
def plus (a,b):
res = [a[0] + b[0], a[1] + b[1], a[2] + b[2]]
return res
def crosS(a,b):
res=[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]-b[0]]
return res
def miN(a,b):
if a<b:
return a
else:
return b
def maX(a,b):
if a>b:
return a
else:
return b
trim=tr.load("Stanford_Bunny.stl")
trim.rezero()
triangle_list_tr=trim.triangles
triangle_list=triangle_list_tr.tolist()
for triangle in triangle_list:
'vertices of surface triangle'
P1 = triangle[0]
P2 = triangle[1]
P3 = triangle[2]
n = crosS(minus(P1, P2), minus(P3, P2))
n_sum = n[0] + n[1] + n[2]
n[0] = n[0] / abs(n_sum)
n[1] = n[1] / abs(n_sum)
n[2] = n[2] / abs(n_sum)
P1x = triangle[0][0]
P1y = triangle[0][1]
P1z = triangle[0][2]
P2x = triangle[1][0]
P2y = triangle[1][1]
P2z = triangle[1][2]
P3x = triangle[2][0]
P3y = triangle[2][1]
P3z = triangle[2][2]
counter+=1
#Set A start
bbxmin = min(P1x, P2x, P3x)
bbxmax = max(P1x, P2x, P3x)
bbymin = min(P1y, P2y, P3y)
bbymax = max(P1y, P2y, P3y)
bbzmin = min(P1z, P2z, P3z)
bbzmax = max(P1z, P2z, P3z)
#Set A End
#Set B Start
P1_xy = [P1[0], P1[1]]
P2_xy = [P2[0], P2[1]]
P3_xy = [P3[0], P3[1]]
if n[2] >= 0:
e_xy_12 = [-1 * (P1[1] - P2[1]), P1[0] - P2[0]]
e_xy_23 = [-1 * (P2[1] - P3[1]), P2[0] - P3[0]]
e_xy_31 = [-1 * (P3[1] - P1[1]), P3[0] - P1[0]]
else:
e_xy_12 = [-1 * (P2[1] - P1[1]), P2[0] - P1[0]]
e_xy_23 = [-1 * (P3[1] - P2[1]), P3[0] - P2[0]]
e_xy_31 = [-1 * (P1[1] - P3[1]), P1[0] - P3[0]]
P1_xz = [P1[0], P1[2]]
P2_xz = [P2[0], P2[2]]
P3_xz = [P3[0], P3[2]]
if n[1] >= 0:
e_xz_12 = [-1 * (P2[2] - P1[2]), P2[0] - P1[0]]
e_xz_23 = [-1 * (P3[2] - P2[2]), P3[0] - P2[0]]
e_xz_31 = [-1 * (P1[2] - P3[2]), P1[0] - P3[0]]
else:
e_xz_12 = [-1 * (P1[2] - P2[2]), P1[0] - P2[0]]
e_xz_23 = [-1 * (P2[2] - P3[2]), P2[0] - P3[0]]
e_xz_31 = [-1 * (P3[2] - P1[2]), P3[0] - P1[0]]
P1_yz = [P1[1], P1[2]]
P2_yz = [P2[1], P2[2]]
P3_yz = [P3[1], P3[2]]
if n[0] >= 0:
e_yz_12 = [-1 * (P1[2] - P2[2]), P1[1] - P2[1]]
e_yz_23 = [-1 * (P2[2] - P3[2]), P2[1] - P3[1]]
e_yz_31 = [-1 * (P3[2] - P1[2]), P3[1] - P1[1]]
else:
e_yz_12 = [-1 * (P2[2] - P1[2]), P2[1] - P1[1]]
e_yz_23 = [-1 * (P3[2] - P2[2]), P3[1] - P2[1]]
e_yz_31 = [-1 * (P1[2] - P3[2]), P1[1] - P3[1]]
#Set B End
del bbxmin
del bbxmax
del bbymin
del bbymax
del bbzmin
del bbzmax
del P1x
del P1y
del P1z
del P2x
del P2y
del P2z
del P3x
del P3y
del P3z
del P1_xy
del P2_xy
del P3_xy
del P1_xz
del P2_xz
del P3_xz
del P1_yz
del P2_yz
del P3_yz
del P1
del P2
del P3
del e_yz_12
del e_yz_23
del e_yz_31
del e_xz_12
del e_xz_23
del e_xz_31
del e_xy_12
del e_xy_23
del e_xy_31
【问题讨论】:
-
我看到你导入 numpy.这将在 PyPy 下运行缓慢,因为它是大量使用 Python C-API 编写的。可能
trimesh也在用C-API,我不熟悉。 -
感谢您的回复。我知道 numpy 和其他基于 C-API 的软件包会降低 pypy 的性能。我使用 trimesh 导入 STL 文件。描述的性能差异出现在程序的不同部分,但你是对的,aorund trimesh 是完美的。 Numpy 不再使用(除了在 trimesh 部分),导入只是旧版本的剩余部分。我会相应地编辑帖子并删除导入。
标签: python memory triangulation pypy voxel