2017-05-04 100 views
1

为了好玩,我正在做一个LeetCode挑战(here),并感到惊讶的是while循环比for循环更有效率。我本来希望编译器生成相同的代码(也按照这些question and answers),但运行时间不同。While循环比循环更有效。可能是什么原因?

while循环大约3 ms,for循环大约需要6 ms。我重复了几次,似乎常常是这样。

不幸的是,我没有测试用例,而且我也没有关于使用的编译器,架构或优化集的任何信息。我认为这并不重要,因为这些程序几乎完全相同,并确实使用相同的编译器,体系结构和选项。

在这个问题上的任何想法或经验?

For循环:

vector<int> twoSum(vector<int>& numbers, int target) { 
    int upper = numbers.size() - 1; 
    int lower = 0; 
    int sum; 

    for (;lower<upper;) { 
     sum = numbers[lower] + numbers[upper]; 
     if (sum == target) { 
      return vector<int> { lower+1, upper+1 }; 
     } else if (sum > target) { 
      upper--; 
     } else { 
      lower++; 
     } 
    } 
} 

While循环:

vector<int> twoSum(vector<int>& numbers, int target) { 
    int upper = numbers.size() - 1; 
    int lower = 0; 
    int sum; 

    while (lower<upper) { 
     sum = numbers[lower] + numbers[upper]; 
     if (sum == target) { 
      return vector<int> { lower+1, upper+1 }; 
     } else if (sum > target) { 
      upper--; 
     } else { 
      lower++; 
     } 
    } 
} 
+1

创建[mcve]。 – user2079303

+3

奇怪;除非代码生成非常差并且优化关闭,否则无法想到它会这样做的原因 –

+1

您运行循环多少次?是否优化?微观基准测试可能非常棘手。 – NathanOliver

回答

0

所有环路遵循相同的模板:

{ 
// Initialize 
LOOP: 
if(!(/* Condition */)) { 
    goto END 
} 

// Loop body 

// Loop increment/decrement 
goto LOOP 
} 
END: 

您的测试必须由可用的处理能力上有不同的中央处理器。

+0

我会避免条件中的否定,这似乎没有必要。 – Jonas

+0

如果否定不存在,那么你的C++编码条件将与它应该是相反的。这是C++ –

+0

的兜帽,这不是我的意思。我会改变if语句来检查条件,然后让if主体包含循环体,递增步和循环。 – Jonas

4

您没有运行足够或足够长的测试,以毫秒为单位的基准很难验证。

更好的方法是比较生成的程序集:for-loopwhile-loop。 使用g ++ 6.3编译代码片段时使用最大优化(-O3)。由此可见,没有性能差异,因为两者的组装完全相同。