This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
bytes_from_utf8(): Use memcpy if all invariant
authorKarl Williamson <khw@cpan.org>
Mon, 5 Jun 2017 18:26:06 +0000 (12:26 -0600)
committerKarl Williamson <khw@cpan.org>
Thu, 8 Jun 2017 17:04:43 +0000 (11:04 -0600)
This function does two passes over the input.  In the first it decides
if the string can be downgraded, and computes the size needed for the
downgraded string.  In the 2nd pass, it does the conversion.

Adding a single 'if' to the function can bypass the 2nd pass completely
if only invariants are found.  The 2nd pass is replaced by a memcpy().

utf8.c

diff --git a/utf8.c b/utf8.c
index 3ded4a6..a439c8e 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -2003,6 +2003,8 @@ Perl_bytes_from_utf8(pTHX_ const U8 *s, STRLEN *len, bool *is_utf8)
     *is_utf8 = FALSE;
 
     Newx(d, (*len) - count + 1, U8);
     *is_utf8 = FALSE;
 
     Newx(d, (*len) - count + 1, U8);
+
+    if (LIKELY(count)) {
     s = start; start = d;
     while (s < send) {
        U8 c = *s++;
     s = start; start = d;
     while (s < send) {
        U8 c = *s++;
@@ -2015,7 +2017,14 @@ Perl_bytes_from_utf8(pTHX_ const U8 *s, STRLEN *len, bool *is_utf8)
     }
     *d = '\0';
     *len = d - start;
     }
     *d = '\0';
     *len = d - start;
+
     return (U8 *)start;
     return (U8 *)start;
+    }
+    else {
+        Copy(start, d, *len, U8);
+        *(d + *len) = '\0';
+        return (U8 *)d;
+    }
 }
 
 /*
 }
 
 /*