Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

*str and *str++

Tags:

c

char

pointers

I have this code (my strlen function)

size_t slen(const char *str)
{
    size_t len = 0;
    while (*str)
    {
        len++;
        str++;
    }
    return len;
}

Doing while (*str++), as shown below, the program execution time is much larger:

while (*str++)
{
    len++;
}

I'm doing this to probe the code

int main()
{
    double i = 11002110;
    const char str[] = "long string here blablablablablablablabla"
    while (i--)
        slen(str);

    return 0;
}

In first case the execution time is around 6.7 seconds, while in the second (using *str++), the time is around 10 seconds!

Why so much difference?

like image 411
Ulrira Avatar asked May 30 '11 19:05

Ulrira


People also ask

What is the difference between char * str and char str []?

What is the difference between char and char*? char[] is a character array whereas char* is a pointer reference. char[] is a specific section of memory in which we can do things like indexing, whereas char* is the pointer that points to the memory location.

What does * str mean in C?

*str takes value from address of str ; c = *str assigns this value to c ; (c = *str) != 0 checks if this value is not NULL . NULL is the end of string marker in C/C++, see "null terminated string" en.wikipedia.org/wiki/Null-terminated_string.

What does * str ++ do in C?

The expression str++ yields the value before incrementing its operand. So you are calling the function with the same value of str. From the C Standard (6.5.2.4 Postfix increment and decrement operators)

What happens if you use str () on a string?

The str() function converts values to a string form so they can be combined with other strings.


3 Answers

Probably because the post-increment operator (used in the condition of the while statement) involves keeping a temporary copy of the variable with its old value.

What while (*str++) really means is:

while (tmp = *str, ++str, tmp)
  ...

By contrast, when you write str++; as a single statement in the body of the while loop, it is in a void context, hence the old value isn't fetched because it's not needed.

To summarise, in the *str++ case you have an assignment, 2 increments, and a jump in each iteration of the loop. In the other case you only have 2 increments and a jump.

like image 148
Blagovest Buyukliev Avatar answered Oct 20 '22 08:10

Blagovest Buyukliev


Trying this out on ideone.com, I get about 0.5s execution with *str++ here. Without, it takes just over a second (here). Using *str++ was faster. Perhaps with optimisation on *str++ can be done more efficiently.

like image 42
Node Avatar answered Oct 20 '22 08:10

Node


This depends on your compiler, compiler flags, and your architecture. With Apple's LLVM gcc 4.2.1, I don't get a noticeable change in performance between the two versions, and there really shouldn't be. A good compiler would turn the *str version into something like

IA-32 (AT&T Syntax):

slen:
        pushl %ebp             # Save old frame pointer
        movl  %esp, %ebp       # Initialize new frame pointer
        movl  -4(%ebp), %ecx   # Load str into %ecx
        xor   %eax, %eax       # Zero out %eax to hold len
loop:
        cmpb  (%ecx), $0       # Compare *str to 0
        je    done             # If *str is NUL, finish
        incl  %eax             # len++
        incl  %ecx             # str++
        j     loop             # Goto next iteration
done:
        popl  %ebp             # Restore old frame pointer
        ret                    # Return

The *str++ version could be compiled exactly the same (since changes to str aren't visible outside slen, when the increment actually occurs isn't important), or the body of the loop could be:

loop:
        incl  %ecx             # str++
        cmpb  -1(%ecx), $0     # Compare *str to 0
        je    done             # If *str is NUL, finish
        incl  %eax             # len++
        j     loop             # Goto next iteration
like image 22
Hoa Long Tam Avatar answered Oct 20 '22 06:10

Hoa Long Tam