样本1
for(int i = 0 ; i <= 99 ; i++)
printf("Hello world");
样本2
printf("Hello world"); // 1st print
printf("Hello world"); // 2nd print
.
.
.
printf("Hello world"); // 100th print
我知道样本1比样本2花费更多时间执行,样本2在文本段中占用更多内存。
但是, 我想知道幕后发生了什么。
答案 0 :(得分:3)
想象一下,样本一被编写为这一系列操作:
i = 0
if (i <= 99)
print
i++
jump
if (i <= 99)
print
i++
jump
if (i <= 99)
print
i++
jump
...
虽然第二个样本很简单:
print
print
print
print
...
这是非常简化的,但你应该明白这一点 - 第一个示例执行更多指令以完成循环。
作为旁注 - 这是编译器经常进行的优化之一 - 它将展开循环并将其编译为好像没有循环。要做到这一点,它必须得出结论它是值得的 - 请注意,样本2将编译成更多的指令总数,并将在内存中占用更多空间(因此将需要更长的时间来加载)。
答案 1 :(得分:0)
如果编程正确,样本2的代码可以更快。
如您所述,有100个printf调用(&#34; ...&#34;);与参数相同的字符串。如果编译器是一个优化编译器,它可以检测到你传递了完全相同的参数,并且在调用之后不会弹出指针,所以它不需要再次推送它以进行下一次调用。
此外,循环之间的速度差异是跳回循环开始所花费的时间。使用现有的体系结构,这甚至可以是一个优势,因为整个循环代码由CPU缓存(这不能通过大量类似的调用来完成)并且不需要进行内存访问来获取指令,从而补偿执行循环指令所花费的时间。
但是......即使有一个很好的优化编译器,它也可以检测到你已经将相同的句子放了100次并在一个循环中折叠,并带有一个隐藏的控制变量(如样本1中所示)所以你不要#39;执行时间的差异。
优化编译器用于检测这些类型的构造并更改代码以提高效率。
这种材料的一个很好的参考是:http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools