[pypy-svn] r52731 - pypy/dist/pypy/rpython/module

fijal at codespeak.net fijal at codespeak.net
Wed Mar 19 17:45:50 CET 2008


Author: fijal
Date: Wed Mar 19 17:45:49 2008
New Revision: 52731

Modified:
   pypy/dist/pypy/rpython/module/ll_os.py
Log:
Speed up ll_os.read by about 20x


Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py	(original)
+++ pypy/dist/pypy/rpython/module/ll_os.py	Wed Mar 19 17:45:49 2008
@@ -19,6 +19,11 @@
 from pypy.rlib import rposix
 from pypy.tool.udir import udir
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.rpython.lltypesystem.rstr import mallocstr
+from pypy.rpython.annlowlevel import hlstr
+from pypy.rpython.lltypesystem.llmemory import raw_memcopy, sizeof,\
+     itemoffsetof, cast_ptr_to_adr, offsetof
+from pypy.rpython.lltypesystem.rstr import STR
 
 posix = __import__(os.name)
 
@@ -474,20 +479,28 @@
                                   [rffi.INT, rffi.VOIDP, rffi.SIZE_T],
                                   rffi.SIZE_T)
 
+        offset = offsetof(STR, 'chars') + itemoffsetof(STR.chars, 0)
+
         def os_read_llimpl(fd, count):
             if count < 0:
                 raise OSError(errno.EINVAL, None)
             inbuf = lltype.malloc(rffi.CCHARP.TO, count, flavor='raw')
-            try:
-                got = rffi.cast(lltype.Signed, os_read(rffi.cast(rffi.INT, fd),
-                                inbuf, rffi.cast(rffi.SIZE_T, count)))
-                if got < 0:
-                    raise OSError(rposix.get_errno(), "os_read failed")
-                # XXX too many copies of the data!
-                l = [inbuf[i] for i in range(got)]
-            finally:
+            #try:
+            got = rffi.cast(lltype.Signed, os_read(rffi.cast(rffi.INT, fd),
+                            inbuf, rffi.cast(rffi.SIZE_T, count)))
+            if got < 0:
                 lltype.free(inbuf, flavor='raw')
-            return ''.join(l)
+                raise OSError(rposix.get_errno(), "os_read failed")
+            s = mallocstr(got)
+            source = cast_ptr_to_adr(inbuf) + \
+                     itemoffsetof(lltype.typeOf(inbuf).TO, 0)
+            dest = cast_ptr_to_adr(s) + offset
+            raw_memcopy(source, dest, sizeof(lltype.Char) * got)
+            lltype.free(inbuf, flavor='raw')
+            #for i in range(got):
+            #    s.chars[i] = inbuf[i]
+            #finally:
+            return hlstr(s)
 
         def os_read_oofakeimpl(fd, count):
             return OOSupport.to_rstr(os.read(fd, count))



More information about the Pypy-commit mailing list