这些代码中哪个运行得更快

Which of these codes will run faster

本文关键字:运行 代码      更新时间:2023-10-16

我最近开始考虑优化,现在我知道有很多书籍和文章,但我有一个特别的场景我感兴趣。

a .

for (i = 0; i < limit + 5; i++)
  cout << test;

b .

limit2 = limit +5;
for (i = 0; i < limit2; i++)
  cout << test;

我想知道的是第二段代码是否运行得更快,因为它只需要做一次数学计算,或者计算结果是在循环的生命周期内存储的

假设类型很简单,如int等,如果任何一个合适的编译器在发布版本中没有将这两个示例优化为相同的代码,我会感到非常惊讶。例如,在重载的operator++中,复杂类型可能需要更大的马力。

在这两种情况下,编译器可能会生成相同的机器级指令。不用麻烦了。

完全没有区别。

你不应该在这里麻烦,因为cout << test将使用99%的时间。

几乎所有你可以对代码做的简单转换,编译器也可以做。再加上一些!

相信你的编译器!

B更快。然而,这取决于编译器和优化级别。启用了优化的智能编译器将用b替换A

您关注的优化几乎肯定无关紧要,无论它是如何编译的。专注于为剩下的代码选择正确的算法和设计。配置文件,以找出哪些是慢的,并优化耗时最多的区域。通常10%的代码需要90%的时间。您目前考虑的是90%的代码中非常小的一部分,在几乎所有可能的情况下,除了有一个空循环块之外,它花费的时间远远少于10%。

我想说这没有什么区别,因为在常量折叠/常量传播(编译器的典型优化技术)之后,for循环中的limit + 5 (A)和limit2 (B)将被一个常量值替换(提供限制可以解析为一个常量值)。

所以运行时应该是相同的,但是编译时对于A来说可能会稍微快一些,因为B需要更多的常量传播/常量折叠迭代。但这只是吹毛求疵,应该是不明显的(除非你在Zuse Z1上编译)

我的答案是:

这取决于ilimit的类型,因为问题中没有提到它们的类型(截至目前)。

  • 如果它们是内置类型(如int, short, long, char等),那么不会有太大的区别,至少对于所有实际目的来说不会有明显的差异。这也是因为大多数CPU周期将被cout单独消耗。智能编译器会优化A(可能还有B),为两者发出相同的代码。

  • 如果它们是一些用户定义的类型,并且i的类型重载了operator<operator++, limit的类型重载了operator+,那么这一切都取决于所有这些函数(代码中涉及的操作符重载)是如何定义的。然而,scenario B更有可能更快,因为limit2 = limit +5;只计算一次。

注意:在第二种情况下,表达式limit2 = limit +5涉及到一个函数调用,基本上是这样的:
 limit2 = limit.operator+(5);

场景B避免了这个函数调用的重复,如果它在for循环之外。

用比cout更"原子"的东西测试它,并且使用更多的循环数。无论如何,这些源代码应该生成相同的代码。

可能没有差别。

第二个循环更快的一个可能原因是编译器能够推断出"limit2"的地址没有被取走,但不能推断出"limit"的地址。如果limit的地址在程序的任何地方,那么运算符<<你调用的函数可以通过该指针改变limit,因此它必须在每次循环中重新加载并重新计算表达式。然而,如果你把limit +5复制到一个局部变量中,编译器就会知道合法程序没有办法改变它。