coreutils
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]