【问题标题】:Slow iterating over string using pointers使用指针缓慢迭代字符串
【发布时间】: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


【解决方案1】:

每次将迭代器与“a”进行比较时,都必须取消引用指针,而不仅仅是比较实际的 char 值。在大多数情况下,这是一个可以忽略不计的差异,但它进行了 1,000,000,000 次迭代,这是很明显的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-28
    • 2016-02-11
    • 2012-05-05
    • 2018-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多