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

mccptt67  于 12个月前  发布在  其他
关注(0)|答案(6)|浏览(181)

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

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

字符串
比这更好吗?:

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

iyr7buue

iyr7buue1#

一般来说,如果结果在迭代过程中没有变化,则应避免在循环的条件部分调用函数。
因此,标准形式是:

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

字符串
注意这里的三件事:

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

(我也改变了类型,因为负长度是没有意义的,字符串接口是按照std::string::size_type定义的,在大多数实现中通常是std::size_t)。
虽然.我承认,它的性能比可读性更重要:

  • 双重初始化意味着xlength作用域都是严格的
  • 通过记忆结果,读者不会怀疑长度是否会在迭代期间发生变化
  • 当您不需要使用“旧”值创建临时值时,使用预增量通常更好

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

svujldwt

svujldwt2#

这取决于编译器的内联和优化能力。通常,第二个变体很可能会更快(更好:它会更快或与第一个片段一样快,但几乎不会慢)。
然而,在大多数情况下,这并不重要,所以人们倾向于喜欢第一个变体,因为它很短。

jgovgodb

jgovgodb3#

这取决于你的C++实现/库,唯一的方法是对它进行基准测试。然而,可以肯定的是,第二个版本永远不会比第一个版本慢,所以如果你不修改循环中的字符串,这是一个明智的优化。

q3aa0525

q3aa05254#

您希望达到多高效率?
如果你不修改循环中的字符串,编译器很容易就能看到它的大小没有改变。

pobjuy32

pobjuy325#

s.length()是否内联并返回一个成员变量?则否,否则解引用和将内容放入堆栈的成本,您知道每次迭代将招致的函数调用的所有开销。

wh6knrhe

wh6knrhe6#

虽然我不一定鼓励你这样做,但令人惊讶的是,不断调用.length()似乎比将其存储在int中更快(至少在我的电脑上,请记住,我使用的是i5第四代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 ms
下面是将长度存储在变量中的代码:

#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毫秒。
我知道这个问题已经有了一个公认的答案,但是还没有任何经过实际检验的答案,所以我决定把我的两分钱投进去。

相关问题