【发布时间】:2017-01-03 12:27:05
【问题描述】:
如果我们对字符串使用基于范围的 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
代码:
#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;
}
【问题讨论】:
-
当你测量差异时,你发现了什么?
-
@KerrekSB 有趣的是,没有测量工作的问题如何被发送到测量,而测量工作的问题被告知他们的测量毫无意义,只有拆卸很重要:)
-
为每个生成的代码:godbolt.org/g/b0VZeO - 玩“发现差异”!
-
@Rotem 那是因为你通常应该两者都做。首先检查反汇编,看看生成的代码是否不同。如果没有,测量是没有意义的,否则它是必不可少的。这个问题缺乏双方的研究努力。
-
@Rotem:这可能过于简单化了。有很多不同类型的问题。