7

考虑以下方法:

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 编译器是否优化了我为可读性和调试而放置的额外变量的不必要定义?

4

2 回答 2

11

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

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

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

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

于 2012-11-29T08:13:19.330 回答
0

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

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

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

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

于 2012-11-29T08:45:17.097 回答