[pypy-commit] pypy struct-double: a branch to speedup struct.pack('d', float). currently not working.
alex_gaynor
noreply at buildbot.pypy.org
Sat Mar 3 18:43:10 CET 2012
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: struct-double
Changeset: r53142:c864362c97b7
Date: 2012-03-03 12:42 -0500
http://bitbucket.org/pypy/pypy/changeset/c864362c97b7/
Log: a branch to speedup struct.pack('d', float). currently not working.
diff --git a/pypy/rlib/rstring.py b/pypy/rlib/rstring.py
--- a/pypy/rlib/rstring.py
+++ b/pypy/rlib/rstring.py
@@ -2,10 +2,12 @@
"""
from pypy.annotation.model import (SomeObject, SomeString, s_None, SomeChar,
- SomeInteger, SomeUnicodeCodePoint, SomeUnicodeString, SomePtr, SomePBC)
+ SomeInteger, SomeUnicodeCodePoint, SomeUnicodeString, SomePtr, SomePBC,
+ SomeFloat)
from pypy.rlib.rarithmetic import ovfcheck
+from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.rpython.lltypesystem import lltype
from pypy.tool.pairtype import pair, pairtype
-from pypy.rpython.extregistry import ExtRegistryEntry
# -------------- public API for string functions -----------------------
@@ -94,6 +96,24 @@
class StringBuilder(AbstractStringBuilder):
tp = str
+ def append_float(self, f):
+ import struct
+ from pypy.rpython.lltypesystem import rffi
+
+ T = lltype.typeOf(f)
+ if T == lltype.Float:
+ fmt = "d"
+ elif T == lltype.SingleFloat:
+ fmt = "f"
+ else:
+ raise TypeError("this takes only float and r_singlefloat")
+
+ size = rffi.sizeof(T)
+ self._grow(size)
+
+ self.l.append(struct.pack(fmt, f))
+
+
class UnicodeBuilder(AbstractStringBuilder):
tp = unicode
@@ -125,6 +145,10 @@
assert isinstance(s_size, SomeInteger)
return s_None
+ def method_append_float(self, f):
+ assert isinstance(f, SomeFloat)
+ return s_None
+
def method_getlength(self):
return SomeInteger(nonneg=True)
diff --git a/pypy/rlib/test/test_rstring.py b/pypy/rlib/test/test_rstring.py
--- a/pypy/rlib/test/test_rstring.py
+++ b/pypy/rlib/test/test_rstring.py
@@ -1,7 +1,9 @@
import sys
+from pypy.rlib.rarithmetic import r_singlefloat
from pypy.rlib.rstring import StringBuilder, UnicodeBuilder, split, rsplit
+
def test_split():
assert split("", 'x') == ['']
assert split("a", "a", 1) == ['', '']
@@ -33,6 +35,20 @@
s.append_multiple_char('d', 4)
assert s.build() == "aabcabdddd"
+ s = StringBuilder()
+ s.append("a")
+ s.append_float(3.0)
+ s.append("a")
+ assert s.getlength() == 10
+ assert s.build() == "a\x00\x00\x00\x00\x00\x00\x08 at a"
+
+ s = StringBuilder()
+ s.append("c")
+ s.append_float(r_singlefloat(2.0))
+ s.append("c")
+ assert s.getlength() == 6
+ assert s.build() == "c\x00\x00\x00 at c"
+
def test_unicode_builder():
s = UnicodeBuilder()
s.append(u'a')
@@ -42,4 +58,4 @@
s.append_multiple_char(u'd', 4)
assert s.build() == 'aabcbdddd'
assert isinstance(s.build(), unicode)
-
+
diff --git a/pypy/rpython/lltypesystem/rbuilder.py b/pypy/rpython/lltypesystem/rbuilder.py
--- a/pypy/rpython/lltypesystem/rbuilder.py
+++ b/pypy/rpython/lltypesystem/rbuilder.py
@@ -3,7 +3,7 @@
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rpython.annlowlevel import llstr
from pypy.rpython.rptr import PtrRepr
-from pypy.rpython.lltypesystem import lltype, rstr
+from pypy.rpython.lltypesystem import lltype, rffi, rstr
from pypy.rpython.lltypesystem.lltype import staticAdtMethod, nullptr
from pypy.rpython.lltypesystem.rstr import (STR, UNICODE, char_repr,
string_repr, unichar_repr, unicode_repr)
@@ -51,6 +51,8 @@
('buf', lltype.Ptr(UNICODE)),
adtmeths={'grow':staticAdtMethod(unicodebuilder_grow)})
+FLOAT_ARRAY = lltype.Ptr(lltype.Array(lltype.Float))
+
MAX = 16*1024*1024
class BaseStringBuilderRepr(AbstractStringBuilderRepr):
@@ -116,6 +118,17 @@
ll_builder.used = used
@staticmethod
+ def ll_append_float(ll_builder, f):
+ used = ll_builder.used
+ T = lltype.typeOf(f)
+ size = rffi.sizeof(T)
+ if used + size > ll_builder.allocated:
+ ll_builder.grow(ll_builder, size)
+
+ rffi.cast(FLOAT_ARRAY, lltype.direct_ptradd(ll_builder.buf.chars, used))[0] = f
+ ll_builder.used += size
+
+ @staticmethod
def ll_getlength(ll_builder):
return ll_builder.used
diff --git a/pypy/rpython/rbuilder.py b/pypy/rpython/rbuilder.py
--- a/pypy/rpython/rbuilder.py
+++ b/pypy/rpython/rbuilder.py
@@ -1,8 +1,8 @@
+from pypy.annotation.model import SomeChar, SomeUnicodeCodePoint
+from pypy.rlib.rstring import INIT_SIZE
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.rmodel import Repr
-from pypy.rpython.rmodel import Repr
-from pypy.rpython.lltypesystem import lltype
-from pypy.rlib.rstring import INIT_SIZE
-from pypy.annotation.model import SomeChar, SomeUnicodeCodePoint
class AbstractStringBuilderRepr(Repr):
def rtyper_new(self, hop):
@@ -39,6 +39,11 @@
hop.exception_cannot_occur()
return hop.gendirectcall(self.ll_append_charpsize, *vlist)
+ def rtype_method_append_float(self, hop):
+ vlist = hop.inputargs(self, lltype.Float)
+ hop.exception_cannot_occur()
+ return hop.gendirectcall(self.ll_append_float, *vlist)
+
def rtype_method_getlength(self, hop):
vlist = hop.inputargs(self)
hop.exception_cannot_occur()
@@ -53,7 +58,7 @@
vlist = hop.inputargs(self)
hop.exception_cannot_occur()
return hop.gendirectcall(self.ll_is_true, *vlist)
-
+
def convert_const(self, value):
if not value is None:
raise TypeError("Prebuilt builedrs that are not none unsupported")
diff --git a/pypy/rpython/test/test_rbuilder.py b/pypy/rpython/test/test_rbuilder.py
--- a/pypy/rpython/test/test_rbuilder.py
+++ b/pypy/rpython/test/test_rbuilder.py
@@ -90,7 +90,7 @@
if s:
s.append("3")
return bool(s)
-
+
def func(i):
if i:
s = StringBuilder()
@@ -107,7 +107,7 @@
if s:
s.append(u"3")
return bool(s)
-
+
def func(i):
if i:
s = UnicodeBuilder()
@@ -119,6 +119,19 @@
res = self.interpret(func, [1])
assert res
+ def test_append_float(self):
+ def func(d):
+ s = StringBuilder()
+ s.append("abc")
+ s.append_float(d)
+ s.append("abc")
+ return s.build()
+
+ res = self.ll_to_string(self.interpret(func, [3.0]))
+ assert res == "abc\x00\x00\x00\x00\x00\x00\x08 at abc"
+
+ res = self.ll_to_string(self.interpret(func, [r_singlefloat(2.0)]))
+ assert res == "abc\x00\x00\x00 at abc"
class TestLLtype(BaseTestStringBuilder, LLRtypeMixin):
pass
More information about the pypy-commit
mailing list