B
Bill Pursell
Frederick said:Bill Pursell posted:
I test a pointer like as follows:
if(p)
{
/* Stuff */
}
yes, but how do you **set** the pointer?
Frederick said:Bill Pursell posted:
I test a pointer like as follows:
if(p)
{
/* Stuff */
}
Frederick said:Flash Gordon posted:
What is aliasing? I've never heard of it. (Not being sarcastic)
http://en.wikipedia.org/wiki/Aliasing_(computing)
Indeed, both snippets achieve the same objective -- one is inherently more
efficient though.
Frederick said:size_t my_strlen_array( const char *s ){
unsigned r = 0;
while (s[r]) r++;
return r;
}size_t my_strlen_pointer( const char *s ){
unsigned r = 0;
while (*s++) r++;
return r;
}
size_t my_strlen_pointer_2( const char *const s_0 ){
const char *s = s_0;
while (*s) s++;
return s-s_0;
}
My measurements show my_strlen_array is faster than
either of the pointer versions. YMMV, of course.
How could that possibly be? I would have thought the fastest was:
#include <cassert>
size_t StrLength(char const *const start)
{
int dummy = (assert(start), 0);
char const *p = start;
while(*p++);
return p - start - 1;
}
So, there you have it, on one platform, the difference seems to be just
noise, and on another the array indexing method is actially faster.
yes, but how do you **set** the pointer?
<snipped code>Frederick said:Clark S. Cox III posted:
On my system (Intel Pentium 3, 500 MHz), pointers are 61% faster.
61% is far from negligible.
Try for yourself:
<snipped code>
I did, the difference varied between arrays 4% faster and pointers 11%
faster, depending on target and optimisations.
With a little help form OpenMP and an extra CPU, arrays were 37% faster.
Frederick said:Ian Collins posted:
I don't know what OpenMP is, plus I've never worked with a computer which
had more than one CPU.
Whatever way you've achieved the 37% faster arrays, I wonder could that
power be channelled to speed up the pointers... ?
I'm still curious as to how the array subscripting could possibly be
faster. It seems to be that it'd be faster to:
(1) Dereference a pointer
(2) Increment the pointer
rather than:
(1) Add an integer to a pointer value
(2) Dereference the pointer
(3) Increment the integer
http://www.openmp.orgFrederick said:Ian Collins posted:
I don't know what OpenMP is, plus I've never worked with a computer which
had more than one CPU.
I doubt it, OpenMP works with arrays (or at let that's all I used it for).Whatever way you've achieved the 37% faster arrays, I wonder could that
power be channelled to speed up the pointers... ?
Mainly because the compiler finds it easier to do loop unrolling withI'm still curious as to how the array subscripting could possibly be
faster. It seems to be that it'd be faster to:
(1) Dereference a pointer
(2) Increment the pointer
rather than:
(1) Add an integer to a pointer value
(2) Dereference the pointer
(3) Increment the integer
It ran slower than all the other versions, so I
didn't put it in.
How can that be? It be!
Again, it depends:Frederick said:posted:
Try this... it prints the following on my system:
Strlen1: 9.703000 seconds.
Strlen2: 6.870000 seconds.
Strlen3: 9.704000 seconds.
Strlen4: 9.584000 seconds.
strlen: 0.010000 seconds.
Some CPUs are slower doing indirect access (*p).I would have thought Strlen3 would be the fastest (except for "strlen" of
course). I'm quite suprised however that strlen is so much faster...
Frederick said:posted:
It ran slower than all the other versions, so I
didn't put it in.
How can that be? It be!
Try this... it prints the following on my system:
Strlen1: 9.703000 seconds.
Strlen2: 6.870000 seconds.
Strlen3: 9.704000 seconds.
Strlen4: 9.584000 seconds.
strlen: 0.010000 seconds.
I would have thought Strlen3 would be the fastest (except for "strlen" of
course). I'm quite suprised however that strlen is so much faster...
#include <stddef.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
char const str[] =
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz""abcdefghijklmnopqrstuvwxyz";
typedef struct Stopwatch {
clock_t start_time;
} Stopwatch;
void StopwatchReset(Stopwatch *const p)
{
p->start_time = clock();
}
clock_t StopwatchDuration(Stopwatch *const p)
{
/* Returns time elapsed since
stopwatch was last reset. */
clock_t const now = clock();
return now - p->start_time;
}
size_t Strlen1(char const *const p)
{
size_t i = 0;
while(p) ++i;
return i;
}
size_t Strlen2(char const *p)
{
size_t i = 0;
while(*p++) ++i;
return i;
}
size_t Strlen3(char const *const parg)
{
char const *p = parg;
while (*p++);
return parg - p - 1;
}
size_t Strlen4(char const *const parg)
{
char const *p = parg;
while (*p) ++p;
return parg - p;
}
int main(void)
{
Stopwatch watch;
clock_t dur1,dur2,dur3,dur4,dur5;
size_t i,j=0;
puts("Please wait, this shouldn't take longer than 30 seconds...\n");
for(StopwatchReset(&watch),i = 0;500000 != i;++i)
Strlen1(str);
dur1 = StopwatchDuration(&watch);
for(StopwatchReset(&watch),i = 0;500000 != i;++i)
Strlen2(str);
dur2 = StopwatchDuration(&watch);
for(StopwatchReset(&watch),i = 0;500000 != i;++i)
Strlen3(str);
dur3 = StopwatchDuration(&watch);
for(StopwatchReset(&watch),i = 0;500000 != i;++i)
Strlen4(str);
dur4 = StopwatchDuration(&watch);
for(StopwatchReset(&watch),i = 0;500000 != i;++i)
strlen(str);
dur5 = StopwatchDuration(&watch);
printf("Strlen1: %f seconds.\n",
(double)dur1 / CLOCKS_PER_SEC);
printf("Strlen2: %f seconds.\n",
(double)dur2 / CLOCKS_PER_SEC);
printf("Strlen3: %f seconds.\n",
(double)dur3 / CLOCKS_PER_SEC);
printf("Strlen4: %f seconds.\n",
(double)dur4 / CLOCKS_PER_SEC);
printf(" strlen: %f seconds.\n",
(double)dur5 / CLOCKS_PER_SEC);
return 0;
}
Might the compiler have optimized the true system routine
out of the loop,because nothing is midified in the loop?
(And then throw out the empty for loop?)
Frederick said:Sjouke Burry posted:
I had considered that. I also considered how it's nice to snip quotes.
Frederick Gotham said:Richard Bos posted:
I was implying that it would be a compile-time programmer error if either
pointer were null, not a runtime error.
That fails for at least two reasons. One, assert() doesn't work that
way. Two, most null pointer errors cannot be caught at compile time.
Frederick said:Let's take a simple function:
void Func(int *const p)
{
assert(p);
*p = 5;
}
In the finished program, it shouldn't make a difference whether NDEBUG is
defined or not, because Func should never be called with a null pointer.
If it IS called with a null pointer, it's not a runtime error,
but rather an error that the programmer made in writing the function
which calls Func.
The programmer made a mistake in writing the caller (or perhaps the
caller's caller, etc), and that mistake resulted in the error of passing
null to `Func`.
Flash said:You might, but I and many others would not. Array subscripting is
perfectly clear in my opinion.
Frederick said:posted:
It ran slower than all the other versions, so I
didn't put it in.
How can that be? It be!
Try this... it prints the following on my system:
[...]
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.