省略号表示的代码几乎肯定会将任何实际性能差异归结为仅仅是噪音。但是,您的所有假设并不正确。
每次迭代都需要将 max 加载到处理器中的寄存器中,然后在 i 和 max 之间进行比较
也许,但可能不是。这取决于您的代码,但任何健全的优化编译器都将能够检测计数器是否在迭代之间发生变化。
我不确定你从哪里得到一些想法,但它们有点误导,没有考虑优化编译器的工作原理。看看你的反汇编,看看你自己的真正区别是什么。哦,到底是什么,我会做的(反正很有趣):
该程序是:
int main(int argc, char *argv[]){
int max = 10;
for (int i = max-1; i >= 0; i--)
{
cout << i;
}
return 0;
}
生成的程序集(VS2010 版本,我自己的评论)是:
int main(int argc, char *argv[]){
00341000 push esi
int max = 10;
for (int i = max-1; i >= 0; i--)
00341001 mov esi,9 ; move a static 9 into esi
00341006 jmp main+10h (341010h)
00341008 lea esp,[esp] ; load the address of whatever
0034100F nop ; esp points to in memory
{ ; (not a memory fetch, just address calculation)
cout << i;
00341010 mov ecx,dword ptr [__imp_std::cout (342048h)]
00341016 push esi
00341017 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (342044h)]
0034101D dec esi ; decrement counter
0034101E jns main+10h (341010h) ; jump if not signed
}
而对于更惯用的版本......
int main(int argc, char *argv[]){
00AC1000 push esi
int max = 10;
for (int i = 0; i < max; i++)
00AC1001 xor esi,esi
{
cout << i;
00AC1003 mov ecx,dword ptr [__imp_std::cout (0AC2048h)]
00AC1009 push esi
00AC100A call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0AC2044h)]
00AC1010 inc esi ; increment esi
00AC1011 cmp esi,0Ah ; compare to 10 (0Ah)
00AC1014 jl main+3 (0AC1003h) ; if less, jump to top
}
所以是的,第一个版本使用jns
指令(如果没有签名则跳转),因此比较简化了一点(与 0 相比)。它还包含更多说明,但没有比较。
但是,请注意,在第二版中进行的比较也是静态的。它知道max
在整个循环中都不会改变,因此它可以相应地优化该位。
但我要强烈重申,这不太可能产生可观的性能优势。即使是我的 Windows PC 上的高性能计时器也无法为我提供两者之间的良好统计差异,因为调用cout
比循环指令花费的时间要长得多。