2017-05-04 161 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)。由此可見,沒有性能差異,因爲兩者的組裝完全相同。