2017-01-03 59 views
0

如果我們使用範圍爲基礎的用繩子圈,有沒有使用基於範圍的循環,哪一個更快?

for (auto const & c : s) 

for (auto c : s) 

// c => char 
// s => std::string 

我問這是因爲字符其在內存中只是一個字節都沒有任何好處拷貝的代價高昂,這讓我很好奇,昨晚。

我做了一些基準測試!

結果:

// In Milliseconds 

// 1000 
// BY COPY: 7 
// BY _REF: 5 

// 10000 
// BY COPY: 51 
// BY _REF: 50 

// 100000 
// BY COPY: 503 
// BY _REF: 501 

// 1000000 
// BY COPY: 5047 
// BY _REF: 5101 

// 10000000 
// BY COPY: 52058 
// BY _REF: 56160 

CODE:

#include <chrono> 
#include <iostream> 
#include <string> 

using std::cout; 
using std::endl; 

bool by_copy(std::string const & s); 
bool by_const_ref(std::string const & s); 

int main() { 
    std::string const test {"0000000001"}; 

    auto start {std::chrono::steady_clock::now()}; 
    for (unsigned long long i {}; i < 10000000; ++i) { 
     bool b {by_copy(test)}; 
     if (b) {} 
    } 
    auto end {std::chrono::steady_clock::now()}; 
    auto duration {std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()}; 
    cout << "BY COPY: " << duration << '\n'; 

    start = std::chrono::steady_clock::now(); 
    for (unsigned long long i {}; i < 10000000; ++i) { 
     bool b {by_const_ref(test)}; 
     if (b) {} 
    } 
    end = std::chrono::steady_clock::now(); 
    duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); 
    cout << "BY _REF: " << duration << '\n'; 

    return 0; 
} 

bool by_copy(std::string const & s) { 
    for (auto c : s) { 
     if (c == '1') { 
      return true; 
     } 
    } 
    return false; 
} 

bool by_const_ref(std::string const & s) { 
    for (auto const & c : s) { 
     if (c == '1') { 
      return true; 
     } 
    } 
    return false; 
} 

UPDATE

出於好奇,我也做了基準的指數,它是方式多爲什麼比基於範圍的循環更快?

成績

// 1000 
    // BY COPY: 7 
    // BY _REF: 5 
    // BYINDEX: 4 

    // 10000 
    // BY COPY: 59 
    // BY _REF: 58 
    // BYINDEX: 37 

    // 100000 
    // BY COPY: 526 
    // BY _REF: 495 
    // BYINDEX: 326 

    // 1000000 
    // BY COPY: 5751 
    // BY _REF: 5038 
    // BYINDEX: 3308 

    // 10000000 
    // BY COPY: 62202 
    // BY _REF: 63002 
    // BYINDEX: 38744 

的BY_INDEX功能:

bool by_index(std::string const & s) { 
    for (size_t i {}; i < s.size(); ++i) { 
     if (s[i] == '1') { 
      return true; 
     } 
    } 
    return false; 
} 
+6

當你測量差異時,你發現了什麼? –

+3

@KerrekSB有趣的是,如何將沒有測量工作的問題發送到度量和測量工作的問題被告知他們的測量毫無意義,而且只有反彙編很重要:) – Rotem

+0

我還沒有測量它。 –

回答

1

爲了澄清,我理解你的問題,例如,你是遍歷字符串中的字符 - 而不是迭代一個字符串容器。

不,沒有優勢。實際上,由於隱含的間接性,理論上可能會導致參考速度較慢。但是,這兩種變體很可能編譯爲完全相同的機器碼,因爲體面優化器將能夠避免間接指令。

+0

在第二種情況下沒有對字符串構造函數的調用,而第一種情況下沒有? – 2017-01-03 12:38:41

+0

@RawN如果's'是一個字符串,那麼'c'是一個字符。那裏沒有構造函數。 – NathanOliver

+0

@RawN不,在這兩種情況下都沒有構建任何字符串。 – user2079303