【发布时间】:2014-07-16 00:50:44
【问题描述】:
我正在尝试使用实例化绘制几千个粒子。它可以工作而且速度很快,但我有一个瓶颈会减慢整个程序的速度。
我的Particle 类是这样的:
public class Particle
{
public Vector2 Position;
//More data not used for drawing
//....
}
现在在我的DrawLoop() 中,我得到了这样的信息:
Vector2[] instanceData = new Vector2[numParticles];
public void Draw()
{
for(int i = 0; i < numParticles; ++i)
instanceData[i] = Particles[i].Position; //THAT'S the slow part
instanceBuffer.SetData(instanceData);
//Now draw VertexBuffer using instancing
//...
}
我尝试过使用Parallel.For,但速度不够快,因为我有大约 8000 个粒子。我还查看了来自 MSDN 的 particlesystem 示例。但他们的Particle struct 只包含用于绘制粒子的数据,并且位置是在着色器中计算的。但是,我需要一些算法的额外数据。
想不出类设计,所以不需要每帧都给数组分配粒子位置。
【问题讨论】:
-
你可以通过使循环不安全的代码和使用指针来加速它。可能是数组边界检查需要花费大量时间。当然,您也可以尝试将循环替换为
instanceData = Particles.Select(p => p.Position).ToArray();,看看是否更快。 -
哇,使用 Select() 确实有很大帮助!现在它的速度提高了 80 倍。谢谢!
-
快 80 倍?真的吗?我觉得很难相信——Select() 并没有做任何神奇的事情,它只是在循环中运行,就像你正在做的那样。此外,在主循环中使用 LINQ 是一个糟糕的主意。它在整个托管堆上分配内存。我怀疑这里发生了一些更微妙的事情。
-
对于 8000 个粒子,我得到 1.2714698s - for loop 0.2745342s - Parallel.For() 0.0023655s - LINQ。这比 for 快 537 倍,比 Parallel.For 快 116 倍,如果我做对了的话。使用其他数量的粒子时速度提高了 80 倍,但我不记得我使用了多少
-
这个循环需要 1 又 25 秒 来执行 8000 个粒子?这段代码中的
Particles是什么?