From 9f2fa50748e52046ea3b99bd469f846ef8827272 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 17 May 2022 18:55:43 -0700 Subject: [PATCH] sort: remove some gotos * src/sort.c (keycompare): Rework to avoid gotos. This also shrinks the machine code a bit (112 bytes) with GCC 12 x86-64 -O2. Nowadays compilers are smart enough to coalesce jumps so we need not do it by hand. --- src/sort.c | 55 +++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/sort.c b/src/sort.c index 72debe0ca5..29c9f39f3c 100644 --- a/src/sort.c +++ b/src/sort.c @@ -2721,15 +2721,17 @@ keycompare (struct line const *a, struct line const *b) while (textb < limb && ignore[to_uchar (*textb)]) \ ++textb; \ if (! (texta < lima && textb < limb)) \ - break; \ + { \ + diff = (texta < lima) - (textb < limb); \ + break; \ + } \ diff = to_uchar (A) - to_uchar (B); \ if (diff) \ - goto not_equal; \ + break; \ ++texta; \ ++textb; \ } \ \ - diff = (texta < lima) - (textb < limb); \ } \ while (0) @@ -2739,37 +2741,37 @@ keycompare (struct line const *a, struct line const *b) else CMP_WITH_IGNORE (*texta, *textb); } - else if (lena == 0) - diff = - NONZERO (lenb); - else if (lenb == 0) - goto greater; else { - if (translate) + size_t lenmin = MIN (lena, lenb); + if (lenmin == 0) + diff = 0; + else if (translate) { - while (texta < lima && textb < limb) + size_t i = 0; + do { - diff = (to_uchar (translate[to_uchar (*texta++)]) - - to_uchar (translate[to_uchar (*textb++)])); + diff = (to_uchar (translate[to_uchar (texta[i])]) + - to_uchar (translate[to_uchar (textb[i])])); if (diff) - goto not_equal; + break; + i++; } + while (i < lenmin); } else - { - diff = memcmp (texta, textb, MIN (lena, lenb)); - if (diff) - goto not_equal; - } - diff = lena < lenb ? -1 : lena != lenb; + diff = memcmp (texta, textb, lenmin); + + if (! diff) + diff = (lena > lenb) - (lena < lenb); } if (diff) - goto not_equal; + break; key = key->next; if (! key) - break; + return 0; /* Find the beginning and limit of the next field. */ if (key->eword != SIZE_MAX) @@ -2792,11 +2794,6 @@ keycompare (struct line const *a, struct line const *b) } } - return 0; - - greater: - diff = 1; - not_equal: return key->reverse ? -diff : diff; } @@ -2835,8 +2832,12 @@ compare (struct line const *a, struct line const *b) a 3% increase in performance for short lines. */ diff = xmemcoll0 (a->text, alen + 1, b->text, blen + 1); } - else if (! (diff = memcmp (a->text, b->text, MIN (alen, blen)))) - diff = alen < blen ? -1 : alen != blen; + else + { + diff = memcmp (a->text, b->text, MIN (alen, blen)); + if (!diff) + diff = (alen > blen) - (alen < blen); + } return reverse ? -diff : diff; } -- 2.47.2