【发布时间】:2013-04-19 09:41:13
【问题描述】:
我很想知道为什么以下解决方案之一比另一个慢得多。让我们考虑以下代码:
// create a very long string
int x,y;
bool b;
char c[10000];
for (x=0;x<10000;x++)
c[x]='a';
string s(c);
现在我想遍历字符串并将每个字符与其他字符进行比较。第一个解决方案在 5 秒内完成任务:
for (y=0;y<100000;y++){
for (x=0;x<10000;x++){
b = (s[x]=='a');
}}
21 秒后的第二个:
string::iterator begin = s.begin();
string::iterator end = s.end();
string::iterator i;
for (y=0;y<100000;y++){
for (i=begin;i<end;i++){
b = (*i=='a');
}}
为什么第二个这么慢?
【问题讨论】:
-
你的编译(优化)设置是什么?如果您没有使用 Release(-O2 或 -O3),那么它根本没有任何意义。实际上,第二个版本(迭代器)应该稍微快一点。
-
您是否正在测试优化的构建?另外,尝试预增加你的字符串迭代器:
++i. -
第一个变体应该允许更积极的优化,编译器可以很容易地推断出
s在循环内实际上是恒定的,而在第二个习惯用法中它必须确定没有发生指针别名。 -
@danilo2:所以教训是:除非您使用的是经过优化的发布版本,否则不要担心性能。调试版本有很多保护措施,因此无法知道哪些部分是实际处理,哪些部分只是调试开销。
-
@collapsar:哈哈,恢复得很好,我会答应你的。 ;) 但实际上,当你想到它时,每次迭代递增的指针只需要一次加法和一次解引用,而随机访问需要两次加法(索引和地址计算)和一次解引用,这就解释了差异。 :)
标签: c++ performance algorithm profiling std