diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2005-05-09 23:54:26 +0000 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2005-05-09 23:54:26 +0000 |
commit | d766c0a42a6877cc36d9018815b377577a00ee92 (patch) | |
tree | 5ce8d5a508688259c76a5516232b79d819191230 /lib | |
parent | a7864df9ba736f8b8a5989bf894aa4068ffbc0a0 (diff) | |
download | coreutils-d766c0a42a6877cc36d9018815b377577a00ee92.tar.xz |
(fts_sort): Optimize the common case where all pointers smell the same.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ChangeLog | 3 | ||||
-rw-r--r-- | lib/fts.c | 16 |
2 files changed, 17 insertions, 2 deletions
diff --git a/lib/ChangeLog b/lib/ChangeLog index 36f403497..97b0c4702 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -7,7 +7,8 @@ * fts.c (__P): Remove. All uses rewritten to assume C89 or better. (fts_open): Don't cast a function value in a possibly-unsafe way. (fts_compar): New function. - (fts_sort): Use it. + (fts_sort): Use it. But optimize the common case where all + pointers smell the same. 2005-05-08 Paul Eggert <eggert@cs.ucla.edu> @@ -1240,6 +1240,20 @@ fts_sort (FTS *sp, FTSENT *head, register size_t nitems) { register FTSENT **ap, *p; + /* On most modern hosts, void * and FTSENT ** have the same + run-time representation, and one can convert sp->fts_compar to + the type qsort expects without problem. Use the heuristic that + this is OK if the two pointer types are the same size, and if + converting FTSENT ** to long int is the same as converting + FTSENT ** to void * and then to long int. This heuristic isn't + valid in general but we don't know of any counterexamples. */ + FTSENT *dummy; + int (*compare) (void const *, void const *) = + ((sizeof &dummy == sizeof (void *) + && (long int) &dummy == (long int) (void *) &dummy) + ? (int (*) (void const *, void const *)) sp->fts_compar + : fts_compar); + /* * Construct an array of pointers to the structures and call qsort(3). * Reassemble the array in the order returned by qsort. If unable to @@ -1263,7 +1277,7 @@ fts_sort (FTS *sp, FTSENT *head, register size_t nitems) } for (ap = sp->fts_array, p = head; p; p = p->fts_link) *ap++ = p; - qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), fts_compar); + qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), compare); for (head = *(ap = sp->fts_array); --nitems; ++ap) ap[0]->fts_link = ap[1]; ap[0]->fts_link = NULL; |