局部变量与实例变量

时间:2012-07-27 08:37:38

标签: c# .net optimization instance local

我一直在为使用XNA构建的游戏进行大量C#优化研究,我仍然不太清楚局部变量是否是实例变量,在不断更新和使用时会提供更好的性能。

根据http://www.dotnetperls.com/optimization,您应该避免参数和局部变量,这意味着实例变量是性能方面的最佳选择。

但是不久之前,我在另一篇StackOverflow帖子(我似乎无法找到它的位置)上读到,局部变量存储在内存的一部分中,访问速度更快,并且每次都是实例变量设置后,必须先擦除上一个值作为一个繁琐的额外步骤,然后才能分配新值。

我知道在设计方面,它可能会破坏封装以在这种情况下使用实例变量,但我对性能非常好奇。目前在我的游戏中,我将局部变量传递给一个类中的7个方法中的3个,但我可以轻松地将变量提升为实例变量,并且能够完全避免参数传递和局部变量。

哪个更好?

3 个答案:

答案 0 :(得分:2)

您的变量是引用(类,字符串)还是值(结构)类型?

对于引用类型,将它们作为方法参数传递并将它们保存在对象实例上没有任何有意义的区别。在第一种情况下,当进入函数时,参数将(对于具有小参数计数的函数)最终在寄存器中。在第二种情况下,引用存在于由“this”指向内存中的数据的偏移量。两种方案都是快速获取内存地址,然后从内存中取出相关数据(这是一个昂贵的部分)。

对于值类型,上面适用于某些类型(可以放入CPU寄存器的整数或浮点数)。对于那些具体的事情来说,价值传递可能要便宜一些,而不是将它们从“这个”中提取出来。对于其他值类型(DateTime或您可能自己构造的结构或任何具有多个成员的结构),当数据太大而无法通过寄存器传入时,这将不再重要。

但是,这很不可能,这对于你的应用程序(甚至游戏)的性能都很重要。最常见的.NET性能问题(不仅仅是低效的算法)将以某种形式来自垃圾生成。这可以通过意外的拳击,使用不良的弦乐构建或不良的物体生命周期管理来表现出来(你的物体的寿命既不短也不长/永久)。

答案 1 :(得分:1)

就个人而言,我不认为这是性能问题的罪魁祸首(除非你经常传递大struct个)。我天真的理解是GC压力是XNA游戏的常用考虑因素,所以基本上要节省对象实例。

如果变量是方法本地的,则值本身或引用(当引用类型时)将位于堆栈上。如果将它们提升为类成员变量,它们将位于堆上类的内存中。

方法调用在技术上会变得更快,因为您不再复制调用中的引用或值(因为如果方法也是类的本地方法,可能会从方法中删除参数)。

我不确定相对表现,但对我而言,似乎如果你需要坚持这个价值,那么价值在课堂上就会有意义......

对我来说,似乎任何有利于另一方的任何潜在收益都会被两者之间的微妙差异所抵消 - 使它们大致相当或差别小而不关心。

当然,面对来自性能分析的硬数字,所有这一切都要得到纠正。

答案 2 :(得分:1)

不传递参数会稍快,不会初始化本地对象(如果它们是对象)会更快。

你在两篇文章中读到的内容并不矛盾,有人提到通过论证会花费时间,另一方面提到初始化对象(在本地对象中)也会花费时间。

关于分配新对象,您可以做的一件事是重用对象而不是丢弃它们。例如,前段时间,我不得不为交易者编写一些代码,这些代码可以用C / C ++和C#实时计算一些产品的价格。通过不从头开始重新创建方程系统,但仅仅通过从先前系统逐步更新系统,我获得了性能的重大提升。

这避免了为新对象分配内存,初始化新对象,并且通常系统几乎相同,所以我只需要修改微小的位来更新它。

通常,在进行任何优化之前,您需要确保优化会显着影响整体性能的内容吗?