【问题标题】:Will one-time usages of local variables be optimized at compile time?是否会在编译时优化局部变量的一次性使用?
【发布时间】:2012-08-26 10:46:12
【问题描述】:
double calcTaxAmount() {
    double price = getA() * getB() + getC();
    double taxRate = getD() + getE();
    return price * taxRate;
}

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

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

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

【问题讨论】:

  • 不确定,但我认为添加 final 可能会有所帮助。我猜编译器足够聪明,可以内联它们
  • 我会更害怕使用 5 个吸气剂。 :-)
  • 代码是为演示目的而编写的。我不会这样编码。我只需要一个简单的例子来表达问题的意图。

标签: java c++ optimization compiler-construction


【解决方案1】:

完全取决于 C 的编译器。对于当前打开了适当优化选项的编译器,大概是的。

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

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

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

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

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

【讨论】:

  • JIT 编译器也是编译器。
  • @delnan 虽然是这样,但在 java 生态系统中,编译器 严格指的是 javac,而不是 JIT。 (这是有道理的,因为 Java 语言没有指定它的执行方式)。
  • 我不知道 Java 生态系统中的约定是什么。然而,虽然有趣的是 javac 不太可能对此进行优化,但我认为这种区别不值得混淆(阅读:我认为你应该说“字节码编译器”或只是“javac”)。
  • @delnan 猜猜为什么编译器后面的括号中有 javac?
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

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

    如果你让它们const 我想不出一个编译器不能优化它。

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

    【讨论】:

      【解决方案4】:

      一般是的。

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

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

      【讨论】:

        猜你喜欢
        • 2018-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-17
        • 1970-01-01
        • 2017-05-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多