Author: Antonio Cuni <[email protected]>
Branch: faster-rstruct-2
Changeset: r91280:09d1f6469168
Date: 2017-05-13 14:53 +0200
http://bitbucket.org/pypy/pypy/changeset/09d1f6469168/

Log:    add a fastpath for floats and doubles

diff --git a/rpython/rlib/rstruct/standardfmttable.py 
b/rpython/rlib/rstruct/standardfmttable.py
--- a/rpython/rlib/rstruct/standardfmttable.py
+++ b/rpython/rlib/rstruct/standardfmttable.py
@@ -23,6 +23,39 @@
 native_is_bigendian = struct.pack("=i", 1) == struct.pack(">i", 1)
 native_is_ieee754 = float.__getformat__('double').startswith('IEEE')
 
[email protected]()
+def pack_fastpath(TYPE):
+    """
+    Create a fast path packer for TYPE. The packer returns True is it succeded
+    or False otherwise.
+    """
+    @specialize.argtype(0)
+    def do_pack_fastpath(fmtiter, value):
+        size = rffi.sizeof(TYPE)
+        pos = fmtiter.pos
+        if (not USE_FASTPATH or
+            fmtiter.bigendian != native_is_bigendian or
+            not native_is_ieee754 or
+            pos % size != 0):
+            raise CannotWrite
+        #
+        # typed_write() might raise CannotWrite
+        fmtiter.result.typed_write(TYPE, fmtiter.pos, value)
+        fmtiter.advance(size)
+    #
+    @specialize.argtype(0)
+    def do_pack_fastpath_maybe(fmtiter, value):
+        try:
+            do_pack_fastpath(fmtiter, value)
+        except CannotWrite:
+            if not ALLOW_SLOWPATH:
+                raise ValueErro("fastpath not taken :(")
+            return False
+        else:
+            return True
+    #
+    return do_pack_fastpath_maybe
+
 def pack_pad(fmtiter, count):
     fmtiter.result.setzeros(fmtiter.pos, count)
     fmtiter.advance(count)
@@ -68,24 +101,14 @@
     fmtiter.advance(1)
     _pack_string(fmtiter, string, count-1)
 
[email protected]()
-def pack_fastpath(TYPE):
-    @specialize.argtype(0)
-    def do_pack_fastpath(fmtiter, value):
-        size = rffi.sizeof(TYPE)
-        pos = fmtiter.pos
-        if (not USE_FASTPATH or
-            fmtiter.bigendian != native_is_bigendian or
-            pos % size != 0):
-            raise CannotWrite
-        # the following might raise CannotWrite and abort the fastpath
-        fmtiter.result.typed_write(TYPE, fmtiter.pos, value)
-        fmtiter.advance(size)
-    return do_pack_fastpath
 
-def make_float_packer(size):
+def make_float_packer(TYPE):
+    size = rffi.sizeof(TYPE)
     def packer(fmtiter):
         fl = fmtiter.accept_float_arg()
+        if pack_fastpath(TYPE)(fmtiter, fl):
+            return
+        # slow path
         try:
             result = ieee.pack_float(fmtiter.result, fmtiter.pos,
                                      fl, size, fmtiter.bigendian)
@@ -150,13 +173,8 @@
         if not min <= value <= max:
             raise StructError(errormsg)
         #
-        try:
-            pack_fastpath(TYPE)(fmtiter, value)
+        if pack_fastpath(TYPE)(fmtiter, value):
             return
-        except CannotWrite:
-            if not ALLOW_SLOWPATH:
-                # we enter here only in some tests
-                raise ValueError("fastpath not taken :(")
         #
         pos = fmtiter.pos + size - 1        
         if fmtiter.bigendian:
@@ -303,7 +321,7 @@
 
     @specialize.argtype(0)
     def unpack_int_fastpath_maybe(fmtiter):
-        if fmtiter.bigendian != native_is_bigendian or not native_is_ieee754: 
## or not str_storage_supported(TYPE):
+        if fmtiter.bigendian != native_is_bigendian or not native_is_ieee754:
             return False
         try:
             intvalue = unpack_fastpath(TYPE)(fmtiter)
@@ -356,9 +374,9 @@
           'needcount' : True },
     'p':{ 'size' : 1, 'pack' : pack_pascal, 'unpack' : unpack_pascal,
           'needcount' : True },
-    'f':{ 'size' : 4, 'pack' : make_float_packer(4),
+    'f':{ 'size' : 4, 'pack' : make_float_packer(rffi.FLOAT),
                     'unpack' : unpack_float},
-    'd':{ 'size' : 8, 'pack' : make_float_packer(8),
+    'd':{ 'size' : 8, 'pack' : make_float_packer(rffi.DOUBLE),
                     'unpack' : unpack_double},
     '?':{ 'size' : 1, 'pack' : pack_bool, 'unpack' : unpack_bool},
     }
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to