Is using strlen() in the loop condition slower than just checking for the null character?

StackOverflow https://stackoverflow.com/questions/3388029

  •  07-10-2020
  •  | 
  •  

Frage

I have read that use of strlen is more expensive than such testing like this:

We have a string x 100 characters long.

I think that

for (int i = 0; i < strlen(x); i++)

is more expensive than this code:

for (int i = 0; x[i] != '\0'; i++)

Is it true? Maybe the second code will not work in some situation so is it better to use the first?

Will it be better with the below?

for (char *tempptr = x; *tempptr != '\0'; tempptr++)
War es hilfreich?

Lösung

for (int i=0;i<strlen(x);i++)

This code is calling strlen(x) every iteration. So if x is length 100, strlen(x) will be called 100 times. This is very expensive. Also, strlen(x) is also iterating over x every time in the same way that your for loop does. This makes it O(n^2) complexity.

for (int i=0;x[i]!='\0';i++)

This code calls no functions, so will be much quicker than the previous example. Since it iterates through the loop only once, it is O(n) complexity.

Andere Tipps

The first code checks length of x in every iteration of i and it takes O(n) to find the last 0, so it takes O(n^2), the second case is O(n)

Yes your second may not work 100% percent of the time but it would be slighty quite. This is because when using strlen() you have to call the method each time. A better way would be like so

int strLength = strlen(x);
for (int i = 0; i < strLength; i++)

Hope this helps.

I can suppose that in first variant you find strlen each iteration, while in second variant you don't do that.
Try this to check:

int a = strlen(x); 
for (int i = 0; i < a; i++) {...}

If no there's no compilation optimization. Yes because strlen will iterate on every byte of the string every time and the second implementation will do it only once.

I guess the compiler could optimize (check Gregory Pakosz comment) your first for loop so that you would be like this:

int len = strlen(x);
for (int i = 0; i < len; i++)

Which is still O(n).

Anyway, I think your second for loop will be faster.

It's worth noting that you may be opening yourself up to buffer overflow problems if you don't also test the index against the size of the buffer containing the string. Depending on what you're doing with this code, this may or may not be a practical issue, but it rarely hurts to have extra checks, and it's a good habit to get into.

I'd suggest: for (i = 0; i < buf_size && x[i] != '\0'; i++)

Where:

  • buf_size is the predetermined size of the buffer. If x is an array, this will be sizeof(x); if x is a pointer, you should have the buffer size available.
  • I've removed the declaration of i from the loop because it's only valid c99. If you're only compiling under c99, feel free to put it back in.

Of course the first one will take longer than the second. They don't actually do the same thing at all--the first one is calculating the length of the string each time; the second one is (effectively) doing it only once.

The first version is equivalent to this:

for (int i=0; x[i] != 0; i++)
  for (int j=0; j<i; j++)
    ;

Maybe you meant to say "is it more efficient to call a library strlen() than to implement my own?" The answer to that is, of course, "it depends". Your compiler may have intrinsic versions of strlen() that are optimized beyond what you would expect from source, you may be on a platform on which function calls are expensive (rare nowadays), etc.

The only answer that's both general and correct is "profile and find out".

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top