为了账号安全,请及时绑定邮箱和手机立即绑定

访问网格顶点性能问题

访问网格顶点性能问题

C#
UYOU 2021-11-28 19:36:15
我遇到此代码运行缓慢的问题(执行循环大约需要 250 毫秒)mesh.triangles.Length 是 8700。我在最新的 Unity 平台(版本 2018.2.3)上使用 c#。我怀疑这是因为我每次迭代都在两个数组之间切换,即。我从三角形中取一个值,然后查找它的顶点元素。mesh.triangles 是一个整数数组。mesh.vertices 是 Vector3 的数组。while (j < mesh.triangles.Length)  {    m_Particles [currentParticlePos].position =  vertices[mesh.triangles[j]];       // allocate a particle to every 3rd vertex position.    j = j + 3;    currentParticlePos++;}
查看完整描述

3 回答

?
阿晨1998

TA贡献2037条经验 获得超6个赞

在这里手动强制进行一些微优化可能会对您有所帮助。


首先,mesh.triangles是一个属性,有自己的 getter 和 setter。每次循环都会对性能造成轻微影响。因此,让我们在循环开始之前将该地址存储为局部变量。


其次, 的值mesh.triangles.Length始终相同。因此,让我们将其存储在局部变量中,而不是在每个循环中调用该属性。


从那以后,您的代码使用vertices [ ]而您的问题是指mesh.vertices [ ]. 如果您正在检查mesh.vertices [ ]每个循环,您还需要在本地存储它。


现在,根据编译器的不同,以下微优化可能已经完成。因此,您必须使用计时技术来验证这是否值得。说了这么多,现在让我们看一下代码:


int [ ] triangles = mesh.triangles;

int length= triangles.Length;

int [ ] vertices = mesh.vertices;


while (j < length)  

{

  m_Particles [ currentParticlePos++ ].position = vertices [ triangles [ j ] ];   

  // allocate a particle to every 3rd vertex position.

  j = j + 3;

}

作为旁注,虽然现在对您没有帮助,但 C#7.x 引入ref struct了一些其他有用的功能,可以加快访问速度,将所有内容保留在堆栈中。这篇文章很有趣,当 Unity 迎头赶上时会很有用。


编辑:如果您的网格没有改变(这很可能),您可以预先定义您需要的确切顶点数组。然后你也只需要增加一个变量。这是一个极端的微观优化。这可能有助于 CPU 预取...(在此处插入耸肩表情符号)。


// The mesh. Assigned as you see fit.

Mesh mesh;


// The length of the new vertices array, holding every third vertex of a triangle.

int length = 0; 


// The new vertices array holding every third vertex.

Vector3 [ ] vertices;


void Start ( )

{

    int [ ] triangles = mesh.triangles;

    length = triangles.Length / 3;

    vertices = new Vector3 [ length ];


    for ( int count = 0; count < length; count++ )

        vertices [ count ] = mesh.vertices [ triangles [ count * 3 ] ] ;

}


private void Update ( )

{

    int j = 0;

    while ( j < length )

    {

        m_Particles [ j ].position = vertices [ j++ ];

    }

}


查看完整回答
反对 回复 2021-11-28
?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

您正在使用mesh但没有修改任何值。在这种情况下,您可以考虑sharedMesh改用。mesh在您的特定情况下,问题在于,mesh创建一个副本并返回它。有了它,sharedMesh您就可以摆脱网格的另一个实例的额外开销。查看meshsharedMesh的文档以获取更多信息。


查看完整回答
反对 回复 2021-11-28
?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

循环运行不慢;此循环、Unity 引擎和您可能拥有或不拥有的任何其他资产的时间为 250 毫秒。


查看完整回答
反对 回复 2021-11-28
  • 3 回答
  • 0 关注
  • 209 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信