在循环中使用string.length()是否有效?

时间:2011-02-27 19:16:45

标签: c++ string optimization

例如,假设string s是这样的:

for(int x = 0; x < s.length(); x++)

比这更好?:

int length = s.length();
for(int x = 0; x < length; x++)

谢谢, 乔尔

6 个答案:

答案 0 :(得分:12)

通常,如果在迭代期间结果没有改变,则应避免在循环的条件部分中进行函数调用。

因此,规范形式是:

for (std::size_t x = 0, length = s.length(); x != length; ++x);

注意事项3:

  • 初始化可以初始化多个变量
  • 条件以!=而不是<
  • 表示
  • 我使用预增量而不是后增量

(我也更改了类型,因为负长度是无意义的,字符串接口是以std::string::size_type为术语定义的,在大多数实现中通常为std::size_t

虽然......我承认它不是为了表现而是为了可读性:

  • 双重初始化意味着xlength范围都必要紧密
  • 通过记忆结果,读者不会怀疑在迭代过程中长度是否会有所不同
  • 如果您不需要使用“旧”值创建临时值
  • ,则使用预增量通常会更好

简而言之:使用最好的工具来完成手头的工作:)

答案 1 :(得分:4)

这取决于编译器的内联和优化功能。通常,第二个变体很可能会更快(更好:它会比第一个片段更快或更快,但几乎从不慢)。

然而,在大多数情况下,这并不重要,因此人们倾向于选择第一个变体,因为它的简洁性。

答案 2 :(得分:3)

这取决于您的C ++实现/库,唯一可以确定的方法是对其进行基准测试。但是,实际上确定第二个版本永远不会比第一个版本慢,所以如果你不修改循环中的字符串,那么这是一个合理的优化。

答案 3 :(得分:1)

您希望效率如何?

如果不修改循环内的字符串,编译器将很容易看到大小不会改变。不要让它变得比你更复杂!

答案 4 :(得分:0)

s.length()是否内联并返回成员变量?然后不,否则解除引用和放入堆栈的成本,你知道每次迭代都会产生函数调用的所有开销。

答案 5 :(得分:0)

虽然我并不一定鼓励你这样做,但似乎不断调用.length()比将其存储在int更快,令人惊讶的是(至少在我的电脑上,请记住我正在使用带有i5 4th gen的MSI游戏笔记本电脑,但它不应该真正影响哪种方式更快。)

常数呼叫的测试代码:

#include <iostream>

using namespace std;

int main()
{
    string g = "01234567890";
    for(unsigned int rep = 0; rep < 25; rep++)
    {
        g += g;
    }//for loop used to double the length 25 times.
    int a = 0;
    //int b = g.length();
    for(unsigned int rep = 0; rep < g.length(); rep++)
    {
        a++;
    }
    return a;
}

根据Code :: Blocks

,平均来说,这个时间为385毫秒

这里是将长度存储在变量中的代码:

#include <iostream>

using namespace std;

int main()
{
    string g = "01234567890";
    for(unsigned int rep = 0; rep < 25; rep++)
    {
        g += g;
    }//for loop used to double the length 25 times.
    int a = 0;
    int b = g.length();
    for(unsigned int rep = 0; rep < b; rep++)
    {
        a++;
    }
    return a;
}

这平均约为420毫秒。

我知道这个问题已经有了一个公认的答案,但是还没有任何实际测试过的答案,所以我决定把2美分投入。我和你有同样的问题,但我没有&#39;在这里找到任何有用的答案,所以我进行了自己的实验。