【问题标题】:PyPy performance falling off dramaticallyPyPy 性能急剧下降
【发布时间】: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


【解决方案1】:

如果代码有很多嵌套 if else,Pypy 会更慢。 CPython 已经针对 if else 进行了更多优化。如果你以正确的方式使用python(不像C)那么pypy会更快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 2015-12-24
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多