]> git.eshelyaron.com Git - emacs.git/commitdiff
Speed up count_size_as_multibyte
authorMattias Engdegård <mattiase@acm.org>
Wed, 16 Feb 2022 11:27:59 +0000 (12:27 +0100)
committerMattias Engdegård <mattiase@acm.org>
Wed, 16 Feb 2022 11:33:35 +0000 (12:33 +0100)
This function is used in many places to calculate the length of
a unibyte string converted to multibyte.

* src/character.c (count_size_as_multibyte): Move the overflow test
outside the loop, which makes it much faster.  Standard compilers
will even vectorise it if asked to (-O2 in Clang, -O3 in GCC).

src/character.c

index eba417d005dfb120746328e36830af7e4bd42d0b..c1a1b553891c3f0c1872385e6c35bde70f9d771c 100644 (file)
@@ -654,15 +654,14 @@ str_as_multibyte (unsigned char *str, ptrdiff_t len, ptrdiff_t nbytes,
 ptrdiff_t
 count_size_as_multibyte (const unsigned char *str, ptrdiff_t len)
 {
-  const unsigned char *endp = str + len;
+  /* Count the number of non-ASCII (raw) bytes, since they will occupy
+     two bytes in a multibyte string.  */
+  ptrdiff_t nonascii = 0;
+  for (ptrdiff_t i = 0; i < len; i++)
+    nonascii += str[i] >> 7;
   ptrdiff_t bytes;
-
-  for (bytes = 0; str < endp; str++)
-    {
-      int n = *str < 0x80 ? 1 : 2;
-      if (INT_ADD_WRAPV (bytes, n, &bytes))
-        string_overflow ();
-    }
+  if (INT_ADD_WRAPV (len, nonascii, &bytes))
+    string_overflow ();
   return bytes;
 }