Commits

Alex Gaynor committed d9e23b1

Speed up StringBuilder.append_charpsize

Comments (0)

Files changed (2)

rpython/rtyper/lltypesystem/rbuilder.py

                                     rstr.copy_unicode_contents)
 
 STRINGBUILDER = lltype.GcStruct('stringbuilder',
-                               ('allocated', lltype.Signed),
-                               ('used', lltype.Signed),
-                               ('buf', lltype.Ptr(STR)),
-                               adtmeths={'grow':staticAdtMethod(stringbuilder_grow)})
+    ('allocated', lltype.Signed),
+    ('used', lltype.Signed),
+    ('buf', lltype.Ptr(STR)),
+    adtmeths={
+        'grow': staticAdtMethod(stringbuilder_grow),
+        'copy_raw_to_string': staticAdtMethod(rstr.copy_raw_to_string),
+    }
+)
 
 UNICODEBUILDER = lltype.GcStruct('unicodebuilder',
-                                 ('allocated', lltype.Signed),
-                                 ('used', lltype.Signed),
-                                 ('buf', lltype.Ptr(UNICODE)),
-                              adtmeths={'grow':staticAdtMethod(unicodebuilder_grow)})
+    ('allocated', lltype.Signed),
+    ('used', lltype.Signed),
+    ('buf', lltype.Ptr(UNICODE)),
+    adtmeths={
+        'grow': staticAdtMethod(unicodebuilder_grow),
+        'copy_raw_to_string': staticAdtMethod(rstr.copy_raw_to_unicode),
+    }
+)
 
 MAX = 16*1024*1024
 
         used = ll_builder.used
         if used + size > ll_builder.allocated:
             ll_builder.grow(ll_builder, size)
-        for i in xrange(size):
-            ll_builder.buf.chars[used] = charp[i]
-            used += 1
-        ll_builder.used = used
+        ll_builder.copy_raw_to_string(charp, ll_builder.buf, used, size)
+        ll_builder.used += size
 
     @staticmethod
     def ll_getlength(ll_builder):

rpython/rtyper/lltypesystem/rstr.py

     copy_string_to_raw._always_inline_ = True
     copy_string_to_raw = func_with_new_name(copy_string_to_raw, 'copy_%s_to_raw' % name)
 
-    return copy_string_to_raw, copy_string_contents
+    @jit.oopspec('stroruni.copy_raw_to_string(ptrsrc, dst, dststart, length)')
+    def copy_raw_to_string(ptrsrc, dst, dststart, length):
+        # xxx Warning: same note as above apply: don't do this at home
+        assert length >= 0
+        # from here, no GC operations can happen
+        dst = _get_raw_buf(SRC_TP, dst, dststart)
+        adr = llmemory.cast_ptr_to_adr(ptrsrc)
 
-copy_string_to_raw, copy_string_contents = _new_copy_contents_fun(STR, STR, Char, 'string')
-copy_unicode_to_raw, copy_unicode_contents = _new_copy_contents_fun(UNICODE, UNICODE,
+        srcbuf = adr + llmemory.itemoffsetof(typeOf(ptrsrc).TO, 0)
+        llmemory.raw_memcopy(srcbuf, dst, llmemory.sizeof(CHAR_TP) * length)
+        # end of "no GC" section
+        keepalive_until_here(dst)
+
+    return copy_string_to_raw, copy_raw_to_string, copy_string_contents
+
+copy_string_to_raw, copy_raw_to_string, copy_string_contents = _new_copy_contents_fun(STR, STR, Char, 'string')
+copy_unicode_to_raw, copy_raw_to_unicode, copy_unicode_contents = _new_copy_contents_fun(UNICODE, UNICODE,
                                                                     UniChar, 'unicode')
 
 CONST_STR_CACHE = WeakValueDictionary()