7
double calcTaxAmount() {
    double price = getA() * getB() + getC();
    double taxRate = getD() + getE();
    return price * taxRate;
}

上面的函数计算纳税金额。

价格和费率是通过调用其他一些函数来计算的。

我引入了两个局部变量 price 和 taxRate 只是为了提高代码的可读性,所以它们都只会使用一次。大多数现代编译器会在编译时替换和内联这些“一次性”局部变量吗?

4

4 回答 4

4

一般是的。

Java 仅在多次调用(默认为 10,000 次)后才将代码优化为本机代码。

即使每次有 1 ns 的差异,您也需要调用此方法 10 亿次才能添加 2 秒的延迟。如果它只有 1000 万次,您不太可能注意到差异。

于 2012-08-31T15:31:19.713 回答
4

显然,这取决于编译器。相当多的编译器在优化方面实际上是脑残,因为它们处理的动态语言足够复杂,以至于大多数优化都是无效的,而许多其他的只有在满足非常严格的条件时才是安全的(例如,任何函数调用几乎可以产生任何影响)。例如,所有 Python 实现都具有编译器,但它们中的大多数只做了很少的窥孔优化,这可能不足以消除所有开销。

也就是说,如果您谈论的是静态类型语言(您的示例暗示了这一点),那么通常是的。活性分析可以检测等价(你仍然需要一个存储位置,但生命周期是一样的),任何合理的寄存器分配器都可以避免不必要的溢出值。

也就是说,这是一个非常糟糕的优化重点。如果您真的想更快地制作东西,请查看带有真实场景的最终代码和配置文件。如果您要进行微优化,请应用一些常识。即使假设此函数是热点,实际计算和获取值也可能很容易花费 100 倍以上的时间。与堆栈存储相比,非内联函数调用需要相当长的时间,并且在此级别上缓存未命中也相当昂贵。

于 2012-08-31T15:31:32.583 回答
1

只要编译器可以证明它们没有被别名和外部修改,编译器就应该能够优化它们(我怀疑它可以在这里确定)。

如果你制作它们,const我想不出一个无法优化它的编译器。

话虽如此,这听起来像是过早的优化,即使代码稍微慢一点,我也不会更改代码,因为它增加了清晰度。

于 2012-08-31T15:31:49.603 回答
1

完全取决于 C 的编译器。对于打开了适当优化选项的当前编译器来说,可能是肯定的。

对于 Java,它不会编译器(javac) 优化,但它可能会在代码实际执行时被 JIT 优化。

也就是说,这些局部变量无论如何都会增加很少的开销。如果编译器决定将表达式优化为等价于:

 return (getA() * getB() + getC()) * (getD() + getE());

它仍然需要某种形式的临时存储(堆栈或寄存器)来存储子表达式的中间结果。所以无论如何它不应该有太大的不同。

我不会担心它,而是选择提供更好可读性的东西。

于 2012-08-31T16:18:01.617 回答