我今天在C#和Java中阅读了post about performance improvement。
我仍然坚持这个:
19。不要过度使用实例变量
使用局部变量可以提高性能。示例1中的代码执行速度比示例2中的代码快。
例1:
public void loop() {
int j = 0;
for ( int i = 0; i<250000;i++){
j = j + 1;
}
}
示例2:
int i;
public void loop() {
int j = 0;
for (i = 0; i<250000;i++){
j = j + 1;
}
}
实际上,我不明白为什么在我可以对字段进行简单访问时,每次调用loop
函数时实例化一些内存并释放它应该更快。
这是纯粹的好奇心,我不是试图将变量'i'放在类的范围内:p 这是真的,使用局部变量更快吗?或者只是在某种情况下?
答案 0 :(得分:10)
堆叠得更快然后堆。
void f()
{
int x = 123; // <- located in stack
}
int x; // <- located in heap
void f()
{
x = 123
}
不要忘记the principle of locality data。应该在CPU缓存中更好地缓存本地数据。如果数据接近,它们将完全加载到CPU缓存中,并且CPU不必从内存中获取它们。
答案 1 :(得分:6)
性能低至获取变量所需的步骤数。本地变量地址在编译时是已知的(它们是堆栈上的已知偏移量),用于访问加载对象“this”的成员以获取实际对象的地址,然后才能获取成员变量的地址。
答案 2 :(得分:4)
即使它会,但在这种情况下几乎没有可衡量的差异。 Probabbly 在第一种情况下,在处理器注册表级别上进行了一些优化,但同样:
就记忆而言,它完全相同,没有任何区别。
第一种情况它通常更好:当你声明变量时它会被立即使用,这是常用的良好模式,因为它是
答案 3 :(得分:1)
我怀疑差异很小,但是在变量是对象成员的情况下,每次访问都需要通过this
(有效)进行间接,而局部变量则不需要。
更一般地说,该对象不需要成员i
,它只在循环的上下文中使用,因此在任何情况下使其在本地使用都更好。
答案 4 :(得分:1)
在C#中,另一个细微差别是生成的MSIL指令的数量(我猜它在Java中类似)。
加载实例字段需要两条指令:
ldarg.0 // load "this" reference onto stack
ldfld MyClass.myField // find the field and load its value
...但只需要一条指令来加载局部变量:
ldloc.0 // load the value at index 0 from the list of local variables
答案 5 :(得分:0)
我测试了500,000次迭代的计算,其中我在本地使用了大约20个变量,并且使用了字段。局部变量测试大约是20毫秒,带有字段的测试大约是30毫秒。使用局部变量时,性能会显着提高。
性能差异是否相关,取决于项目。在您的平均业务应用程序中,性能提升可能不明显,最好是寻找可读/可维护的代码,但我正在开发声音合成软件,其中像这样的纳米优化实际上变得相关。