【问题标题】:Are variable definitions that are used once optimized?一次使用的变量定义是否已优化?
【发布时间】:2012-11-29 08:07:28
【问题描述】:

考虑以下方法:

private static long maskAndNegate(long l) {
    int numberOfLeadingZeros = Long.numberOfLeadingZeros(l)
    long mask = CustomBitSet.masks[numberOfLeadingZeros];
    long result = (~l) & mask;
    return result;
}

方法可简写为:

private static long maskAndNegate(long l) {
    return (~l) & CustomBitSet.masks[Long.numberOfLeadingZeros(l)];
}

这两种表示在实际运行时是否相等?换句话说,Java 编译器是否优化掉了我为了可读性和调试而放置的额外变量的不必要定义?

【问题讨论】:

  • 哪个 Java 编译器?哪个 JIT 编译器?哪个平台?换句话说,获得与你相关的答案的唯一可靠方法是自己测试。没那么难。
  • "Java 编译器是否优化..." 在大多数情况下,编译器不会优化任何东西,iirc。 HotSpot 技术可能会对其进行优化,这可能是您应该研究的。
  • 大多数(如果不是全部)Java 编译器都进行了一些优化。我会将 Oracle、GNU(也许还有 Eclipse)所做的任何优化作为标准。 en.wikipedia.org/wiki/Java_compiler#Major_Java_compilers
  • 编译两个版本。然后使用javap工具(JDK自带)反汇编类文件(使用javap的-c选项)。比较字节码,看看有什么区别。

标签: java variables optimization


【解决方案1】:

Java 编译器本身几乎不做任何优化。几乎所有事情都是由 JIT 完成的。

虽然局部变量本身与优化无关 - 多运算符表达式仍然需要逻辑上的各种操作数进入堆栈,只是在未命名的“槽”中。您可能会发现为您的两个实现生成的字节码非常相似,只是在第二种情况下没有名称。

更重要的是,可能非常偶尔通过减少您使用的局部变量的数量而产生的任何性能优势几乎肯定是微不足道的。第一种方法的可读性优势更可能是显着的。与往常一样,避免在没有证据证明您尝试优化的地方是瓶颈的情况下进行微优化,然后只允许证明其价值的优化。

(当您证明您需要优化特定方法时,您已经拥有测试任何潜在优化的工具,因此您无需猜测。)

【讨论】:

  • 非常感谢您的回答。我是出于好奇而问的——我总是更喜欢可读性,而不是小的、过早的优化。
【解决方案2】:

代码不够大,无法针对初学者进行优化。而在第二种方式中,您只是节省了用于存储对numberOfLeadingZeros 的引用的内存。

但是,当您在运行时足够显着地使用此代码(例如至少 10000 次)时,JIT 会将其识别为 HOT 代码,然后使用诸如方法内联和类似排序之类的巧妙技巧对其进行优化。

但在您的情况下,首选选项是第一个,因为它更可读性。

您不应该为了小的优化而牺牲可读性。

【讨论】:

    猜你喜欢
    • 2012-08-26
    • 2022-12-03
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多