string strLine;//not constant
int index = 0;
while(index < strLine.length()){//strLine is not modified};

strLine.length()的计算次数

我们是否需要在循环之前使用nLength并将nLength分配给strLine.length()

#1楼 票数:4 已采纳

每次通过循环时都会评估length ,但是由于length是恒定时间( O(1) ),它没有太大的区别,添加一个变量来存储这个值可能会产生微不足道的影响代码可读性(以及如果字符串被更改则破坏代码)。

#2楼 票数:3

length()在包含在源文件中的头文件中定义,因此它可以由编译器内联,它的内部调用也可以内联,因此如果编译器能够检测到您的字符串实例未在循环中更改然后它可以优化对字符串长度的访问,因此它只会被评估一次。 在任何情况下,我都不认为存储字符串长度的值是非常必要的。 也许它可以为你节省一些纳米,但是你的代码会更大,当你决定在循环中更改字符串时会有一些风险。

#3楼 票数:2

每次被称为......(每次评估时)。 如果你没有改变字符串长度,你最好用一个临时变量,如:

string strLine;
int stringLength = strLine.length();
int index = 0;
while(index < stringLength);

#4楼 票数:2

我认为这里潜藏着第二个问题,那就是“哪个实施更清晰?”

从语义上讲,如果你指的是strLine的长度永远不会在循环体内发生变化,那么通过指定一个命名良好的变量来明确它。 我甚至会把它变成常量。 这使得其他程序员(和您自己)清楚地知道比较值永远不会改变。

这样做的另一件事是,当您在调试器中单步执行代码时,可以更容易地看到该值是什么。 悬停在本地工作比在函数调用上工作好得多。

说,“把它留作函数调用;编译器将优化它”让我感到过早的悲观。 即使length()是O(1),如果没有内联(你不能保证不会禁用优化),它仍然是一个非常重要的函数调用。 通过使用局部变量,您可以阐明您的意思,并获得可能非平凡的性能优化。

做什么使你的意图最清楚。

#5楼 票数:1

strLine.length()将被评估,而(i <strLine.length())

话虽如此,如果字符串是常量,大多数编译器将优化它(使用适当的设置)。

#6楼 票数:1

如果要使用临时变量,请使用const限定符,因此编译器可以添加优化,因为知道该值不会更改:

string strLine;//not constant
int index = 0;
const int strLenght = strLine.Length();
while(index < strLine.length()){//strLine is not modified};

有可能编译器本身在访问Length()方法时进行了那些优化。

编辑:我的程序集有点生疏,但我认为评估只发生一次。 鉴于此代码:

int main()
{
    std::string strLine="hello world";

    for (int i=0; i < strLine.length(); ++i)
    {
        std::cout << strLine[i] <<std::endl;
    }
}

生成此程序集:

    for (int i=0; i < strLine.length(); ++i)
0040104A  cmp         dword ptr [esp+20h],esi 
0040104E  jbe         main+86h (401086h)

但对于这段代码

 std::string strLine="hello world";
 const int strLength = strLine.length();
 for (int i=0; i < strLength ; ++i)
 {
    std::cout << strLine[i] <<std::endl;
 }

生成这个:

   for (int i=0; i < strLength ; ++i)
0040104F  cmp         edi,esi 
00401051  jle         main+87h (401087h) 

如果不使用const限定符,则会生成相同的程序集,因此在这种情况下它不会产生任何影响。

试过VSC ++ 2005

#7楼 票数:1

如上所述,由于string::length函数可能完全在头文件中定义,并且需要为O(1),因此几乎可以肯定要评估一个简单的成员访问,并将其内联到您的代码中。 由于您没有将字符串声明为volatile,因此允许编译器想象没有外部代码会更改它,并优化对单个内存访问的调用,并将值保留在寄存器中,如果它发现这是一个好主意。

通过自己获取和缓存值,可以增加编译器执行相同操作的机会。 在许多情况下,编译器甚至不会生成将字符串长度写入堆栈的代码,只需将其保留在寄存器中即可。 当然,如果调用编译器无法内联的不同函数,则必须将该值写入堆栈以防止函数调用对寄存器执行操作。

#8楼 票数:0

由于您没有更改字符串,因此不应该使用

const string strLine;

只是,因为那时编译器会获得更多关于什么可以和什么不能改变的信息 - 不确定C ++编译器究竟有多聪明。

#9楼 票数:-1

每次循环时都会评估strLine.length()

你是正确的,因为使用nLength会更有效,特别是如果strLine很长的话。

  ask by yesraaj translate from so

未解决问题?本站智能推荐:

2回复

在C#中,每次都会评估循环声明吗?

这是一个非常挑剔的问题,但好奇心使我变得更好。 每次循环执行时,for循环是否会重新评估RHS条件? 见下文。 在您的代码库中执行以下操作是否是一种好习惯? 还是编译器进行了此类优化/它们可以忽略不计(即使具有庞大的代码库)?
2回复

条件评估是否优化? 这段代码不好吗?

1.Imagine条件if (obj.is_x() || obj.is_y() || obj.is_z()) 如果obj.is_x()返回true,是否会调用obj.is_y()和obj.is_z() ? 这个坏主意(一般来说)? 这段代码看起来不好吗?
6回复

c ++数组评估

有没有办法在C ++中“批量评估”数组的内容? 例如,设int number [10] = {23,42,12,42,53,10,0,0,0,0}。 有没有办法循环遍历数组中的每个元素并检查元素是否满足指定条件? 简而言之,我希望能够做到这样的事情: 要么 对于小数组,
6回复

while循环中的条件顺序

首先,在我开始之前,我使用的是VC ++ 2008专业版,在Windows操作系统上运行Intel core2。 我也知道这个代码永远不会在运行Windows的core2 / corei7上执行。 我有一个带有2个条件的while循环看起来像这样:注意:这是一个非常简化的版本。
5回复

同时执行多条件循环评估C ++

这学期有一个C ++类。 上学期我们正在学习Python,现在要做的一项任务是做一个do-while循环,该循环在变量不等于数组中多个数字之一的情况下循环。 在python中,我将使用“不在”功能,例如: 或类似的东西。 我天真的尝试在C ++中做同样的事情,就像这样: 但
5回复

条件评估

我的主体中有一个if语句,但条件是由多个OR'd表达式组成。 在执行期间,如果在OR'd条件下的第一个表达式为true,第二个表达式是否仍将被求值? 即是更好地有表达式或运算,或让每个表达式形成为一个单一的条件else其中的每一个身体else是一样的吗? 例如
7回复

如何使用循环缩短条件?

我有六个组件数组,我想确保如果用户正在初始化组件的值,他/她将不会给出2个或更多相同的数字。 我试着这样做: 但它不起作用:/
2回复

条件循环:变量与函数?

是否有任何值得选择的理由,例如性能或安全性? --