diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2010-08-08 23:14:38 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2010-08-08 23:15:09 -0700 |
commit | ad31a59a370e29f38864a747045da10c82d6c912 (patch) | |
tree | 033f522838276d0a62da69784109f8fcbde7e1c3 /src/sort.c | |
parent | b877ea4b3ee4c62ab75caedbfdcca4877961aedf (diff) | |
download | coreutils-ad31a59a370e29f38864a747045da10c82d6c912.tar.xz |
sort: speed up -R with long lines in hard locales
* src/sort.c (compare_random): Guess that the output will be
3X the input. This avoids the overhead of calling strxfrm
twice on typical implementations. Suggested by Bruno Haible.
Diffstat (limited to 'src/sort.c')
-rw-r--r-- | src/sort.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/src/sort.c b/src/sort.c index dcfd24f33..148ed3ee7 100644 --- a/src/sort.c +++ b/src/sort.c @@ -2024,6 +2024,7 @@ compare_random (char *restrict texta, size_t lena, char stackbuf[4000]; char *buf = stackbuf; size_t bufsize = sizeof stackbuf; + void *allocated = NULL; uint32_t dig[2][MD5_DIGEST_SIZE / sizeof (uint32_t)]; struct md5_ctx s[2]; s[0] = s[1] = random_md5_state; @@ -2047,6 +2048,16 @@ compare_random (char *restrict texta, size_t lena, /* Store the transformed data into a big-enough buffer. */ + /* A 3X size guess avoids the overhead of calling strxfrm + twice on typical implementations. Don't worry about + size_t overflow, as the guess need not be correct. */ + size_t guess_bufsize = 3 * (lena + lenb) + 2; + if (bufsize < guess_bufsize) + { + bufsize = MAX (guess_bufsize, bufsize * 3 / 2); + buf = allocated = xrealloc (allocated, bufsize); + } + size_t sizea = (texta < lima ? xstrxfrm (buf, texta, bufsize) + 1 : 0); bool a_fits = sizea <= bufsize; @@ -2062,9 +2073,7 @@ compare_random (char *restrict texta, size_t lena, bufsize = sizea + sizeb; if (bufsize < SIZE_MAX / 3) bufsize = bufsize * 3 / 2; - buf = (buf == stackbuf - ? xmalloc (bufsize) - : xrealloc (buf, bufsize)); + buf = allocated = xrealloc (allocated, bufsize); if (texta < lima) strxfrm (buf, texta, sizea); if (textb < limb) @@ -2119,8 +2128,7 @@ compare_random (char *restrict texta, size_t lena, diff = xfrm_diff; } - if (buf != stackbuf) - free (buf); + free (allocated); return diff; } |