开发者

Does making the iterator a pointer speed up a C loop?

I ran the following:

#include <stdio.h>
typedef unsigned short boolean;

#define false 0
#define true (!false)
int main()
{
    int STATUS = 0;
    int i = 0;
    boolean ret = true;
    for(i = 0; i < 99999; i++)
    {
        ret = ret && printf("Hello, World.");
    }
    if(!ret)
    {
        STATUS = -1;
    }

    return STATUS;
}

It completes in just under a second. Typica开发者_如何学Pythonlly 0.9 - 0.92.

Then I changed int i = 0; to int *i = 0; and now I am getting execution times under 0.2 seconds. Why the speed change?


Your runtime is dominated by the time required to print to the console. i++ on an int* will increment the pointer by the size of a pointer. That will be either 4 or 8 depending on your computer and compiler settings. Based on the numbers you report, presumably it would be 4. So printf is executed only a quarter as many times.


Typically, printing to a console will be several orders of magnitude larger than any gain with micro optimization you could do to such a loop.

Are you really sure your second version prints hello world 99999 times as well ?

When you're doing for(int *i = 0; i++ ; i < 99999 ) , you're cheking if the pointer value(an address) is less than 99999, which doesn't normally make a lot of sense. Incrementing a pointer means you step it up to point at the next element, and since you have an int*, you'll increment the pointer by sizeof(int) bytes.

You're just iterating 99999/sizeof(int) times.


Your comment on nos's answer confirmed my suspicion: it's pointer arithmetic. When you increment an int pointer using ++, it doesn't just add one to the number, but it actually jumps up by the size of an integer, which is usually 4 (bytes). So i++ is actually adding 4 to the numeric value of i.

Similarly, if you use += on a pointer, like i += 5, it won't just add 5 (or whatever) to the numeric value of i, it'll advance i by the size of that many integers, so 5*4 = 20 bytes in that case.

The reasoning behind this is that if you have a chunk of memory that you're treating as an array,

int array[100]; // for example

you can iterate over the elements in the array by incrementing a pointer.

int* i = array;
int* end = array + 100;
for (i = array; i < end; i++) { /* do whatever */ }

and you won't have to rewrite the loop if you use a data type of a different size.


The reason is because the increment operates differently on pointers.

On ints, i++ increments i by 1.

For pointers, i++ increments by the size of the pointed-to object, which will be 4 or 8 depending on your architecture.

So your loop runs for only 1/4 or 1/8 of the iteration count when i is a pointer vs when i is an int.


The correct way to do this test with a pointer would be something like:

int i;
int *i_ptr = &i; 

for (*i_ptr = 0; *i_ptr < 99999; *i_ptr++) {
    ...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜