[pypy-commit] pypy faster-rstruct-2: migrate pack_float to the new buffer-based interface
antocuni
pypy.commits at gmail.com
Wed May 10 19:05:33 EDT 2017
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: faster-rstruct-2
Changeset: r91229:f3fc7a2efd43
Date: 2017-05-10 17:44 +0200
http://bitbucket.org/pypy/pypy/changeset/f3fc7a2efd43/
Log: migrate pack_float to the new buffer-based interface
diff --git a/rpython/rlib/mutbuffer.py b/rpython/rlib/mutbuffer.py
--- a/rpython/rlib/mutbuffer.py
+++ b/rpython/rlib/mutbuffer.py
@@ -16,7 +16,7 @@
You can call finish() only once.
"""
- _attrs_ = ['readonly', 'll_val']
+ _attrs_ = ['readonly', 'll_val', 'size']
_immutable_ = True
def __init__(self, size):
diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py
--- a/rpython/rlib/rstruct/ieee.py
+++ b/rpython/rlib/rstruct/ieee.py
@@ -265,14 +265,17 @@
return (mant, (sign << BITS - MANT_DIG - 1) | exp)
@jit.unroll_safe
-def pack_float(result, x, size, be):
- l = []
+def pack_float(result, pos, x, size, be):
unsigned = float_pack(x, size)
- for i in range(size):
- l.append(chr((unsigned >> (i * 8)) & 0xFF))
if be:
- l.reverse()
- result.append("".join(l))
+ # write in reversed order
+ for i in range(size):
+ c = chr((unsigned >> (i * 8)) & 0xFF)
+ result.setitem(pos + size - i - 1, c)
+ else:
+ for i in range(size):
+ c = chr((unsigned >> (i * 8)) & 0xFF)
+ result.setitem(pos+i, c)
@jit.unroll_safe
def pack_float80(result, x, size, be):
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
@@ -62,10 +62,14 @@
def packer(fmtiter):
fl = fmtiter.accept_float_arg()
try:
- return ieee.pack_float(fmtiter.result, fl, size, fmtiter.bigendian)
+ result = ieee.pack_float(fmtiter.result, fmtiter.pos,
+ fl, size, fmtiter.bigendian)
except OverflowError:
assert size == 4
raise StructOverflowError("float too large for format 'f'")
+ else:
+ fmtiter.advance(size)
+ return result
return packer
# ____________________________________________________________
diff --git a/rpython/rlib/rstruct/test/test_ieee.py b/rpython/rlib/rstruct/test/test_ieee.py
--- a/rpython/rlib/rstruct/test/test_ieee.py
+++ b/rpython/rlib/rstruct/test/test_ieee.py
@@ -3,6 +3,7 @@
import random
import struct
+from rpython.rlib.mutbuffer import MutableStringBuffer
from rpython.rlib.rstruct import ieee
from rpython.rlib.rfloat import isnan, NAN, INFINITY
from rpython.translator.c.test.test_genc import compile
@@ -73,9 +74,9 @@
assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q)
for be in [False, True]:
- Q = []
- ieee.pack_float(Q, x, 8, be)
- Q = Q[0]
+ buf = MutableStringBuffer(8)
+ ieee.pack_float(buf, 0, x, 8, be)
+ Q = buf.finish()
y = ieee.unpack_float(Q, be)
assert repr(x) == repr(y), '%r != %r, Q=%r' % (x, y, Q)
@@ -197,12 +198,11 @@
class TestCompiled:
def test_pack_float(self):
def pack(x, size):
- result = []
- ieee.pack_float(result, x, size, False)
+ buf = MutableStringBuffer(size)
+ ieee.pack_float(buf, 0, x, size, False)
l = []
- for x in result:
- for c in x:
- l.append(str(ord(c)))
+ for c in buf.finish():
+ l.append(str(ord(c)))
return ','.join(l)
c_pack = compile(pack, [float, int])
diff --git a/rpython/rlib/rstruct/test/test_pack.py b/rpython/rlib/rstruct/test/test_pack.py
--- a/rpython/rlib/rstruct/test/test_pack.py
+++ b/rpython/rlib/rstruct/test/test_pack.py
@@ -15,6 +15,11 @@
def advance(self, count):
self.pos += count
+ def finish(self):
+ # check that we called advance() the right number of times
+ assert self.pos == self.result.getlength()
+ return self.result.finish()
+
def _accept_arg(self):
return self.value
@@ -41,7 +46,7 @@
attrs = self.fmttable[fmt]
pack = attrs['pack']
pack(fake_fmtiter)
- return fake_fmtiter.result.finish()
+ return fake_fmtiter.finish()
def check(self, fmt, value):
expected = struct.pack(self.endianess+fmt, value)
More information about the pypy-commit
mailing list