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++) {
...
精彩评论