D
David Mathog
A piece of code I am working on uses qsort() to sort buffers containing
packed binary fixed length words, however the number of bytes in a word
will vary from one call of qsort() to another. We've discussed here
before how qsort() doesn't provide any nice way to pass in extra data,
so here the number of bytes is smuggled into the comparison function
using the global integer variable gbl_bws (gbl_bws == GloBaL Binary Word
Size). The word size varies but isn't likely to be huge in any case,
with a maximum of probably around 8 bytes. The current code is this:
static int compare_bw1(const void *p1, const void *p2){
unsigned char *uc1 = (unsigned char *)p1;
unsigned char *uc2 = (unsigned char *)p2;
int i;
for(i=0; i < gbl_bws; i++){
if( uc1 > uc2 ){ return 1; }
else if( uc1 < uc2 ){ return -1;}
}
return 0;
}
Another way of doing this is:
static int compare_bw2(const void *p1, const void *p2){
return(memcmp(p1,p2,gbl_bws);
}
Any thoughts on whether the second function form would usually be
faster, slower, or the same?
It seems to me to be pretty compiler dependent in that if the compiler
actually makes a function call to memcmp() that call overhead is going
to add up in a hurry when sorting many billions of words. On the other
hand, if the compiler expands memcmp() in place that code is likely to
be heavily optimized. I know that generally using memcpy() ends up
being faster than using my own code, is that going to be generally true
for memcmp() as well?
On a related note, what does the standard say memcmp() will return for
the following 4 cases? My guesses are shown in the last column.
p1 p2 Guess (why)
1 null null 0 (because they are identical, albeit undefined)
2 null !null -1 (nothing < something )
3 !null null 1 (something > nothing )
-----------------------------------------------
4 n == 0 0 {0 bytes of anything is always nothing)
Since memcmp() only returns a comparison value, and not an error value
which is really what's called for here, it presumably has these
"comparisons" defined in the standard. The man pages I have seen do
not address this point.
Thanks,
David Mathog
packed binary fixed length words, however the number of bytes in a word
will vary from one call of qsort() to another. We've discussed here
before how qsort() doesn't provide any nice way to pass in extra data,
so here the number of bytes is smuggled into the comparison function
using the global integer variable gbl_bws (gbl_bws == GloBaL Binary Word
Size). The word size varies but isn't likely to be huge in any case,
with a maximum of probably around 8 bytes. The current code is this:
static int compare_bw1(const void *p1, const void *p2){
unsigned char *uc1 = (unsigned char *)p1;
unsigned char *uc2 = (unsigned char *)p2;
int i;
for(i=0; i < gbl_bws; i++){
if( uc1 > uc2 ){ return 1; }
else if( uc1 < uc2 ){ return -1;}
}
return 0;
}
Another way of doing this is:
static int compare_bw2(const void *p1, const void *p2){
return(memcmp(p1,p2,gbl_bws);
}
Any thoughts on whether the second function form would usually be
faster, slower, or the same?
It seems to me to be pretty compiler dependent in that if the compiler
actually makes a function call to memcmp() that call overhead is going
to add up in a hurry when sorting many billions of words. On the other
hand, if the compiler expands memcmp() in place that code is likely to
be heavily optimized. I know that generally using memcpy() ends up
being faster than using my own code, is that going to be generally true
for memcmp() as well?
On a related note, what does the standard say memcmp() will return for
the following 4 cases? My guesses are shown in the last column.
p1 p2 Guess (why)
1 null null 0 (because they are identical, albeit undefined)
2 null !null -1 (nothing < something )
3 !null null 1 (something > nothing )
-----------------------------------------------
4 n == 0 0 {0 bytes of anything is always nothing)
Since memcmp() only returns a comparison value, and not an error value
which is really what's called for here, it presumably has these
"comparisons" defined in the standard. The man pages I have seen do
not address this point.
Thanks,
David Mathog