变量性能 - java [重复]

Posted

技术标签:

【中文标题】变量性能 - java [重复]【英文标题】:Variables performance - java [duplicate] 【发布时间】:2015-06-04 23:46:22 【问题描述】:

所以我有一个应用程序可以进行大量数学运算,因此存在大量临时变量。我想知道的是:当我在循环之前声明变量然后重用它(代码 1)时是否有任何性能差异,或者在循环中声明它更好(代码 2)?该变量仅在循环内部需要,n 可以多达数万个。还是将它们作为全局变量更好?该循环也被多次调用。

代码 1:

double temp;
for (int i = 0; i < n; i++) 
   temp = ...;

代码 2:

for (int i = 0; i < n; i++) 
  double temp = ...;

感谢您的提示。

【问题讨论】:

第一部分代码 1 似乎是合乎逻辑的,永远不要在代码中使用全局变量,因为它们会导致很多不需要的结果 你的基准测试显示了什么? 现代JVM会自动检测一段代码何时被调用多次,并在运行该代码块时进行深度优化和编译以提高性能。所以你不应该为此烦恼太多,让 JVM 为你完成这项工作。 【参考方案1】:

不,这在性能上没有区别。 (计算和内存都不明智。)声明不会在运行时“执行”。

其实下面两个sn-ps生成的一模一样字节码:

// Snippet 1                        // Snippet 2
int i;                              int i;
double temp;                        for (i = 0; i < 5; i++)      
for (i = 0; i < 5; i++)                double temp = i;
    temp = i;                       


// Generates                        // Generates

   0: iconst_0                       0: iconst_0
   1: istore_1                       1: istore_1
   2: iload_1                        2: iload_1
   3: iconst_5                       3: iconst_5
   4: if_icmpge     16               4: if_icmpge     16
   7: iload_1                        7: iload_1
   8: i2d                            8: i2d
   9: dstore_2                       9: dstore_2
  10: iinc          1, 1             10: iinc          1, 1
  13: goto          2                13: goto          2

所以,这应该可以回答您关于性能的问题。

现在,我仍然会选择第二种方法,因为它限制了 temp 的范围,即它最少会混淆命名空间。

【讨论】:

只是一个小补充:一旦这个循环被编译成机器码,它将被完全消除。因此,即使字节码不相同,任何用于建立相对速度的微基准测试的幼稚方法都会失败。 是的。对这类事物进行微基准测试会产生完全无用的结果。【参考方案2】:

通常最好declare variables in the smallest scope possible(在循环内)。这样,对象引用将有资格更早地进行垃圾收集,因此您的代码将更有效地使用内存。当声明它们的方法离开堆栈时,原始变量将被释放,但最好在尽可能有限的范围内声明它们。

至于速度方面的考虑,应该没什么区别。 theseanswers中的字节码分析,最终没有区别。

参考文献

Declaring variables inside or outside of a loop Declaring variables inside or outside of a loop Which loop has better performance? Why?

【讨论】:

反对者,愿意发表评论吗? 有人无缘无故对反对票发疯了。好答案,+1。 我没有投反对票,但这些是原始变量(至少在示例中如此),因此它们不会被垃圾回收。 @AndyTurner 虽然这是真的,但在尽可能小的范围内声明变量仍然是合理的做法。 @AndyTurner - 好点,我会澄清一下。【参考方案3】:

很难说两者是否有性能差异,你可以衡量它,但我想你不会发现太大的差异(真的取决于你在做什么和你的编译器)

但是,我认为代码选项 2 是更好的做法,因为它仅在循环中使用,因此您不需要在循环之外对该变量进行任何更广泛的范围界定。

【讨论】:

以上是关于变量性能 - java [重复]的主要内容,如果未能解决你的问题,请参考以下文章

提高Java中字符串连接的性能[重复]

Java远程调试-性能[重复]

从函数调用分配多个返回值的性能[重复]

java中Stream API中“filter()”方法的性能[重复]

Java中的静态最终变量[重复]

论 Java 中获取一组不重复的随机数之性能问题