[pypy-commit] pypy default: Optimized version of next_codepoint_pos() without the JIT

arigo pypy.commits at gmail.com
Fri Feb 15 06:48:57 EST 2019


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r96018:1ab6eb502ac8
Date: 2019-02-12 15:30 +0100
http://bitbucket.org/pypy/pypy/changeset/1ab6eb502ac8/

Log:	Optimized version of next_codepoint_pos() without the JIT

diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py
--- a/rpython/rlib/rarithmetic.py
+++ b/rpython/rlib/rarithmetic.py
@@ -729,7 +729,9 @@
     """ The JIT special-cases this too. """
     from rpython.rtyper.lltypesystem import lltype
     from rpython.rtyper.lltypesystem.lloperation import llop
-    return llop.int_force_ge_zero(lltype.Signed, n)
+    n = llop.int_force_ge_zero(lltype.Signed, n)
+    assert n >= 0
+    return n
 
 def int_c_div(x, y):
     """Return the result of the C-style 'x / y'.  This differs from the
diff --git a/rpython/rlib/rutf8.py b/rpython/rlib/rutf8.py
--- a/rpython/rlib/rutf8.py
+++ b/rpython/rlib/rutf8.py
@@ -19,7 +19,7 @@
 from rpython.rlib.objectmodel import enforceargs, we_are_translated, specialize
 from rpython.rlib.objectmodel import always_inline, dont_inline, try_inline
 from rpython.rlib.rstring import StringBuilder
-from rpython.rlib import jit, types
+from rpython.rlib import jit, types, rarithmetic
 from rpython.rlib.signature import signature, finishsigs
 from rpython.rlib.types import char, none
 from rpython.rlib.rarithmetic import r_uint
@@ -117,6 +117,12 @@
 #        chinese wikipedia, they're anywhere between 10% and 30% slower.
 #        In extreme cases (small, only chinese text), they're 40% slower
 
+#        The following was found by hand to be more optimal than both,
+#        on x86-64...
+_is_64bit = sys.maxint > 2**32
+_constant_ncp = rarithmetic.r_uint64(0xffff0000ffffffff)
+
+ at always_inline
 def next_codepoint_pos(code, pos):
     """Gives the position of the next codepoint after pos.
     Assumes valid utf8.  'pos' must be before the end of the string.
@@ -125,6 +131,11 @@
     chr1 = ord(code[pos])
     if chr1 <= 0x7F:
         return pos + 1
+    if _is_64bit and not jit.we_are_jitted():
+        # optimized for Intel x86-64 by hand
+        return pos + 1 + (
+            ((chr1 > 0xDF) << 1) +
+            rarithmetic.intmask((_constant_ncp >> (chr1 & 0x3F)) & 1))
     if chr1 <= 0xDF:
         return pos + 2
     if chr1 <= 0xEF:
@@ -162,7 +173,6 @@
     ordch1 = ord(code[pos])
     if ordch1 <= 0x7F or pos +1 >= lgt:
         return ordch1
-
     ordch2 = ord(code[pos+1])
     if ordch1 <= 0xDF or pos +2 >= lgt:
         # 110yyyyy 10zzzzzz -> 00000000 00000yyy yyzzzzzz


More information about the pypy-commit mailing list