Question

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

how many times strLine.length() is evaluated

do we need to put use nLength with nLength assigned to strLine.length() just before loop

Was it helpful?

Solution

length will be evaluated every time you go via the loop, however since length is constant time (O(1)) it doesn't make much difference and adding a variable for storing this value will probably have a negligible effect with a small hit on code readability (as well as breaking the code if the string is ever changed).

OTHER TIPS

length() is defined in headers which are included in your source file, so it can be inlined by compiler, it's internal calls also could be inlined, so if compiler would be able to detect that your string instance isn't changed in the loop then it can optimize access to length of a string, so it will be evaluated only once. In any case I don't think that storing value of string's length is really necessary. Maybe it can save you some nanosecs, but your code will be bigger and there will be some risk when you will decide to change that string inside loop.

Each time it is called ... (each while evaluation). If you are not changing the string lenght you are better of with a temporary variable like:

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

I think there is a second question lurking inside this, and that's "which implementation is more clear?"

If, semantically, you mean for the length of strLine to never change inside the body of the loop, make it obvious by assigning to a well named variable. I'd even make it const. This makes it clear to other programmers (and yourself) that the comparison value is never changing.

The other thing this does it make it easier to see what that value is when you're stepping through the code in a debugger. Hover-over works a lot better on a local than it does on a function call.

Saying, "leave it as a function call; the compiler will optimize it" strikes me as premature pessimization. Even though length() is O(1), if not inlined (you can't guarantee that optimizations aren't disabled) it's is still a nontrivial function call. By using a local variable, you clarify your meaning, and you get a possibly non-trivial performance optimization.

Do what makes your intent most clear.

strLine.length() will be evaluated while( i < strLine.length() )

Having said that if the string is constant, most compilers will optimize this( with proper settings ).

If you are going to use a temporally variable use a const qualifier, so the compiler can add optimizations knowing that the value will not change:

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

Chances are that the compiler itself make those optimizations when accessing the Length() method anyway.

Edit: my assembly is a little rusty, but i think that the evaluation takes place just once. Given this code:

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

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

Generates this assembly:

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

But for this code

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

generates this one:

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

The same assembly is generated if a const qualifier is not used, so in this case it doesn't make a difference.

Tried with VSC++ 2005

As stated, since the string::length function is likely entirely defined in a header, and is required to be O(1), it's almost certain to evaluate to a simple member access, and get inlined into your code. Since you don't declare the string as volatile, the compiler is allowed to imagine that no outside code is going to change it, and optimize the call to a single memory access and leave the value in a register if it finds that that is a good idea.

By grabbing and caching the value yourself, you increase the chances that the compiler will be able to do the same thing. In many cases, the compiler will not even generate the code to write the string length into the stack, and just leave it in a register. Of course, if you call out to different functions that the compiler cannot inline, then the value will have to be written to the stack to prevent the function calls from turfing the register.

Since you are not changing the string, shouldn't you be using

const string strLine;

Just, because then the compiler gets some more information on what can and what cannot change - not sure exactly how smart a C++ compiler can get, though.

strLine.length() will be evaluated every time you go around the loop.

You're correct in that it would be more efficient to use nLength, especially if strLine is long.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top