【问题标题】:Variables performance - java [duplicate]变量性能 - java [重复]
【发布时间】: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 为你完成这项工作。

标签: java performance variables


【解决方案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中的字节码分析,最终没有区别。

参考文献

【讨论】:

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

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

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

【讨论】:

    猜你喜欢
    • 2015-08-12
    • 2023-03-17
    • 1970-01-01
    • 2012-09-29
    • 2010-10-01
    • 2019-12-17
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    相关资源
    最近更新 更多