【问题标题】:Difference in speed while accessing an array访问数组时的速度差异
【发布时间】:2012-05-30 16:11:13
【问题描述】:

两者之间有什么区别(我的程序速度 - 执行时间)?

第一个选项:

 private void particleReInit(int loop)
        {
            this.particle[loop].active = true;
            this.particle[loop].life = 1.0f;
            this.particle[loop].fade = 0.3f * (float)(this.random.Next(100)) / 1000.0f + 0.003f; 
            this.particle[loop].r = colors[this.col][0];    // Select Red Rainbow Color
            this.particle[loop].g = colors[this.col][1];    // Select Red Rainbow Color
            this.particle[loop].b = colors[this.col][2];    // Select Red Rainbow Color
            this.particle[loop].x = 0.0f;
            this.particle[loop].y = 0.0f;
            this.particle[loop].xi = 10.0f * (this.random.Next(120) - 60.0f);
            this.particle[loop].yi = (-50.0f) * (this.random.Next(60)) - (30.0f);
            this.particle[loop].xg = 0.0f; 
            this.particle[loop].yg = 0.8f; 
            this.particle[loop].size = 0.2f;
            this.particle[loop].center = new PointF(particleTextures[0].Width / 2, particleTextures[0].Height / 2);

    }

第二个选项:

Particle p = particle[loop];
p.active = true;
p.life = 1.0f;
...


其中Particle particle[] = new Particle[NumberOfParticles]; 只是一个具有生命、位置等属性的粒子数组。


我在 Visual Studio 2010 中像 WFA(Windows 窗体应用程序)一样执行此操作,并且需要提高性能(我们无法使用 OpenGL,因此对于更多粒子,我的程序往往会很慢)。

【问题讨论】:

  • 您可以通过循环执行十亿次来轻松地自行测试。我认为差异(如果有的话)会非常非常微小。
  • 在第二个选项中,您不必每次更改粒子时都使用数组的索引访问器。我不能肯定这是否会提高性能,但它也有助于更好地阅读。
  • 除了访问this.particle[loop].PropertyName 之外,您不是强制对每个属性的数组进行索引搜索吗?我认为在第二个选项中缓存引用将是最好的方法。但是,除非您进行快速测试,否则您不会知道。
  • 这是一种“依赖封装”的方法吗?

标签: c# arrays winforms performance


【解决方案1】:

我当然希望速度会有所不同 - 毕竟它会做更多的工作。另一个线程可能在语句之间更改了数组的内容,这些内容可能(或可能不)在该线程中可见。如果这些是属性而不是字段,则属性设置器甚至可以在 same 线程中更改数组中的值,这将 可见。

速度差异是否显着是另一回事,我们无法判断。

更重要的是,我想说第二种形式比现有代码更清晰

事实上,如果这实际上是为了重新初始化整个元素,我实际上会创建一个 new Particle,然后将其分配给元素:

particle[loop] = new Particle {
    active = true,
    life = 1f,
    // etc
};

... 或创建一个单独的方法/构造函数,以创建处于适当状态的粒子。

【讨论】:

  • 构造函数是否具有性能优势以伴随明显的上下文/可读性改进?
  • 谢谢,这正是我需要知道的。更清晰的 cmets 也有帮助,因为我真的不认为这会对性能产生很大影响,但我想做更好的代码 :) 有很多地方可以提高性能。我首先尝试以某种方式使其工作,现在我正在清理代码..
  • @Jodrell - 没有性能优势,C# 编译器将这些转换为标准字段/属性分配 - 生成的 IL 代码是相同的
【解决方案2】:

虽然速度差异可能非常小,但此处的任何速度差异都可能可以忽略不计。我会使用最容易阅读和维护的版本。

就个人而言,我更喜欢您的第二个选项,因为我发现它更容易阅读。

我在 Visual Studio 2010 中像 WFA(Windows 窗体应用程序)一样执行此操作,并且需要提高性能(我们无法使用 OpenGL .. 所以对于更多粒子,我的程序往往会很慢)。

如果您的目标是性能,我非常怀疑这个例程是您问题的核心。您应该在探查器下运行它。在您真正衡量您的表现并找到真正的问题之前,您只是在猜测并且可能会花时间优化错误的东西。

使用 GDI+ 渲染“粒子”更可能成为瓶颈,并且在您的两个选项之间更改此例程不会对感知速度产生影响。

【讨论】:

  • 我想提高性能,但我不认为会有很大的不同。我正在清理我的代码,也希望它更快地工作。这是改变的第一件事,也是最容易的事情。现在我要改进计算新位置和渲染。
【解决方案3】:

作为替代方案 - 使 Particle 成为一个结构,在循环中按顺序对其进行初始化,我敢打赌它会比这两个选项中的任何一个都快得多。

【讨论】:

  • 我不知道为什么,但我认为从一些非常重要的原因应该是 Particle 一个类。
  • 可能有很多理由为 Particle 使用类,但如果您的目标是获得更好的性能 - 使用 stuct 会快得多(尽管您可能需要稍微调整代码,因为 struct 是值类型)。
猜你喜欢
  • 2010-09-13
  • 2022-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多