performance - 为什么编译器这么蠢?

标签 performance language-agnostic compiler-construction

我总是想知道为什么编译器无法弄清楚人眼显而易见的简单事物。他们做了很多简单的优化,但从来没有做过哪怕一点点复杂的优化。例如,此代码在我的计算机上大约需要 6 秒才能打印值零(使用 java 1.6):

int x = 0;
for (int i = 0; i < 100 * 1000 * 1000 * 1000; ++i) {
    x += x + x + x + x + x;
}
System.out.println(x);

很明显,x 永远不会改变,所以无论你多久向其自身添加 0,它都保持为零。因此理论上编译器可以用 System.out.println(0) 替换它。

或者更好,这需要 23 秒:

public int slow() {
   String s = "x";
   for (int i = 0; i < 100000; ++i) {
       s += "x";
   }
   return 10;
}

首先,编译器可能会注意到我实际上正在创建一个 100000“x” 的字符串 s,因此它可以自动使用 s StringBuilder 来代替,或者甚至更好地直接将其替换为结果字符串,因为它始终是相同的。其次,它无法识别我实际上根本没有使用该字符串,因此整个循环可以被丢弃!

为什么在投入如此多的人力开发快速编译器之后,它们仍然如此相对愚蠢?

编辑:当然,这些都是愚蠢的例子,永远不应该在任何地方使用。但是每当我必须将漂亮且非常可读的代码重写为不可读的代码以便编译器满意并生成快速代码时,我想知道为什么编译器或其他一些自动化工具不能为我完成这项工作。

最佳答案

在我看来,老实说,我不认为编译器的工作就是修复错误的编码。您已经非常明确地告诉编译器您希望执行第一个循环。它等同于:

x = 0
sleep 6 // Let's assume this is defined somewhere.
print x

我不希望编译器仅仅因为我的 sleep 语句什么也没做就删除它。您可能会争辩说 sleep 语句是对延迟的明确请求,而您的示例则不是。但随后您将允许编译器对您的代码应该做什么做出非常高级的决定,我认为这是一件坏事。

代码以及处理它的编译器都是工具,如果你想有效地使用它们,你就需要成为一个工具匠。有多少 12 英寸电锯会拒绝尝试砍伐一棵 30 英寸的树?如果检测到混凝土墙,有多少钻头会自动切换到锤模式?

我怀疑没有,这是因为将其设计到产品中的成本一开始就非常可怕。但更重要的是,如果您不知道自己在做什么,就不应该使用钻头或链锯。例如:如果您不知道什么是反冲(对于新手来说,这是一种非常简单的脱掉 ARM 的方法),请远离电锯,直到您了解为止。

我完全赞成允许编译器提出改进建议,但我宁愿自己维护控制权。编译器不应该单方面决定循环是不必要的。

例如,我在嵌入式系统中完成了定时循环,其中 CPU 的时钟速度是准确已知的,但没有可靠的定时设备可用。在这种情况下,您可以精确计算给定循环将花费多长时间,并使用它来控制事情发生的频率。如果编译器(或在这种情况下的汇编器)认为我的循环无用并优化它使其不存在,那么这将不起作用。

话虽如此,让我给您讲一个 VAX FORTRAN 编译器的老故事,该编译器正在进行性能基准测试,结果发现它比最接近的竞争对手快许多个数量级.

事实证明,编译器注意到基准循环的结果没有在其他地方使用,并将循环优化为遗忘。

关于performance - 为什么编译器这么蠢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/405770/

相关文章:

java - 额外字符串比较与 HashMap 查找的性能

javascript - Dart `startsWith` 是否比 JavaScript 中的相同方法慢?

for-loop - 我应该期望看到 `for` 循环中的计数器在其体内发生变化吗?

python - 鸭子类型(duck typing) : how to avoid name collisions?

Ruby 到 Actionscript3 字节码

javascript - Internet Explorer Javascript 性能问题

performance - 以向量化方式从非标量结构体数组中的元素减去常量值

algorithm - 找到最接近某个位置的非碰撞矩形的有效方法是什么

c++ - llvm::CloneBasicBlock 示例

if-statement - Bison 悬卡在其他地方