diff options
author | Bobby Bingham <koorogi@koorogi.info> | 2014-10-29 23:47:23 -0500 |
---|---|---|
committer | Bobby Bingham <koorogi@koorogi.info> | 2014-10-29 23:47:23 -0500 |
commit | d95320cafb6d6b4a65f9713e54d83229cea1bbfa (patch) | |
tree | 837dc2f81b76602053d80bd89be3531988365bd1 /grailsort.c | |
parent | 9499a9f80823bf936c6b525a3fe3ae8ee8c17e80 (diff) |
Perform swaps in larger chunks in merge step
Provides about a 10% overall speedup for the sorted+noise and reverse+noise
test cases. Increases the number of comparisons in some of the other
cases, but doesn't significantly change the runtime.
Diffstat (limited to 'grailsort.c')
-rw-r--r-- | grailsort.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/grailsort.c b/grailsort.c index a39a0b2..331452d 100644 --- a/grailsort.c +++ b/grailsort.c @@ -29,19 +29,28 @@ size_t merge(char *buf, char *a, char *b, size_t bufnmel, size_t anmel, size_t b { struct counts snapshot = counts[CURRENT]; + char *a_end = a + width * anmel; + char *b_end = b + width * bnmel; + char *buf_end = buf + width * bufnmel; + size_t count; + while (bnmel) { - char *a_tail = tail(a, anmel, width); - char *b_tail = tail(b, bnmel, width); - char *buf_tail = tail(buf, bufnmel, width); - - if (cmp(a_tail, b_tail) <= 0) { - swap(buf_tail, b_tail, width); - bnmel--; - } else { - swap(buf_tail, a_tail, width); - anmel--; + for (count = 0; cmp(a_end-width, b_end-width) > 0; count++) { + anmel -= 1; + bufnmel -= 1; + a_end -= width; + buf_end -= width; } - bufnmel--; + swap(a_end, buf_end, count*width); + + do { + for (count = 0; bnmel && count < bufnmel && cmp(a_end-width, b_end-width) <= 0; count++) { + bnmel -= 1; + b_end -= width; + buf_end -= width; + } + swap(b_end, buf_end, count*width); + } while (count == bufnmel); } add_counts(counts + MERGE, &snapshot); |