[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[INSTALLED 3/5] sort: remove some gotos
From: |
Paul Eggert |
Subject: |
[INSTALLED 3/5] sort: remove some gotos |
Date: |
Tue, 17 May 2022 19:32:23 -0700 |
* 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 72debe0ca..29c9f39f3 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.36.1