访问网格顶点性能问题

时间:2018-08-15 08:12:42

标签: c# unity3d mesh vertices

我遇到了这段代码运行缓慢的问题(执行循环大约需要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++;
}

4 个答案:

答案 0 :(得分:2)

在此处手动强制进行一些微优化可能会帮助您。

首先,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和其他一些有用的功能,这些功能将加快访问速度,并将所有内容保留在堆栈中。 This article是一本有趣的文章,当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++ ];
    }
}

答案 1 :(得分:1)

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

答案 2 :(得分:0)

循环运行不慢;此循环,Unity Engine和您可能拥有或可能没有的其他资产需要250毫秒。

答案 3 :(得分:-1)

我也遇到了这个问题。如果可能,您应该按照三角形数组指定顶点的顺序预先生成顶点数组。否则,您将访问内存中的随机位置,这实际上会破坏性能。