基于范围的循环,哪一个更快?

时间:2017-01-03 12:27:05

标签: c++ string for-loop char

如果我们使用基于范围的for循环与字符串,使用

是否有任何增益
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;
}

更新

出于好奇,我也通过索引做了基准测试,它比基于范围的for循环要快得多,为什么?

结果

    // 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;
}

1 个答案:

答案 0 :(得分:1)

为了澄清,我解释你的问题,使你迭代字符串的字符 - 而不是迭代字符串的容器。

不,没有优势。实际上,由于隐含的间接性,理论上有可能使参考更慢。但是,两种变体很可能编译成完全相同的机器代码,因为一个不错的优化器将能够避免间接。