views:

494

answers:

9
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

A: 

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.

Greg
Unless the body of the while loop changes the contents of the container, of course.
MadKeithV
I believe (as others above), that length is O(1) and thus not dependent on the length of the string.
Daren Thomas
Yes but the point is you're calling .length N times, and the overhead of N function calls can be significant
Greg
+2  A: 

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);
Drejc
Why is that? Getting the Length property is O(1).
Ed Swangren
Even better if you make stringLength a const. After all, we are hoping for the compiler to make this optimisation, so let's do it ourselves. The temp variable cannot be slower than calculating the length on each pass, and may be faster.
Gorpik
As said this pretty much comes down to the compiler used. If the compiler is "smart" enough he will make the optimisation if not we are making the code harder to read. On operations like string lenght this might not be an issue, but on some other operation it can be a performance penalty.
Drejc
+4  A: 

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).

Motti
+1  A: 

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 ).

Maverique
+3  A: 

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.

Dmitriy Matveev
A: 

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.

Daren Thomas
+2  A: 

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.

Rob K
Why worry about performance when optimizations are disabled? If you care about performance, use an optimizing compiler (pretty much all of them are, nowadays), and turn the optimizations on. Otherwise, don't complain about performance.
David Thornley
+1  A: 

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

Ricky AH
Good point for the temp variable.
Gorpik
+1  A: 

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.

Eclipse