optimize READ-STRING-AS-[BYTES|UNSIGNED-BYTE-32]
authorNikodemus Siivola <nikodemus@random-state.net>
Fri, 9 Dec 2011 08:26:00 +0000 (10:26 +0200)
committerNikodemus Siivola <nikodemus@random-state.net>
Fri, 9 Dec 2011 21:52:16 +0000 (23:52 +0200)
  Use FAST-READ-BYTE / FAST-READ-U-INTEGER, and add a separate
  READ-BASE-STRING-AS-BYTES.

  This actually makes a difference in FASL-loading speed.

src/code/fop.lisp

index 24e5c0a..91fa04e 100644 (file)
 ;;; of like READ-SEQUENCE specialized for files of (UNSIGNED-BYTE 8),
 ;;; with an automatic conversion from (UNSIGNED-BYTE 8) into CHARACTER
 ;;; for each element read
-(declaim (ftype (function (stream simple-string &optional index) (values))
-                read-string-as-bytes
-                #!+sb-unicode read-string-as-unsigned-byte-32))
 (defun read-string-as-bytes (stream string &optional (length (length string)))
-  (dotimes (i length)
-    (setf (aref string i)
-          (sb!xc:code-char (read-byte stream))))
-  ;; FIXME: The classic CMU CL code to do this was
-  ;;   (READ-N-BYTES FILE STRING START END).
-  ;; It was changed for SBCL because we needed a portable version for
-  ;; bootstrapping. Benchmark the non-portable version and see whether it's
-  ;; significantly better than the portable version here. If it is, then use
-  ;; it as an alternate definition, protected with #-SB-XC-HOST.
-  (values))
+  (declare (type (simple-array character (*)) string)
+           (type index length)
+           (optimize speed))
+  (with-fast-read-byte ((unsigned-byte 8) stream)
+    (dotimes (i length)
+      (setf (aref string i)
+            (sb!xc:code-char (fast-read-byte)))))
+  string)
+(defun read-base-string-as-bytes (stream string &optional (length (length string)))
+  (declare (type (simple-array base-char (*)) string)
+           (type index length)
+           (optimize speed))
+  (with-fast-read-byte ((unsigned-byte 8) stream)
+    (dotimes (i length)
+      (setf (aref string i)
+            (sb!xc:code-char (fast-read-byte)))))
+  string)
 #!+sb-unicode
 (defun read-string-as-unsigned-byte-32
     (stream string &optional (length (length string)))
+  (declare (type (simple-array character (*)) string)
+           (type index length)
+           (optimize speed))
   #+sb-xc-host (bug "READ-STRING-AS-UNSIGNED-BYTE-32 called")
-  (dotimes (i length)
-    (setf (aref string i)
-          (let ((code 0))
-            (dotimes (k 4 (sb!xc:code-char code))
-              (setf code (logior code (ash (read-byte stream)
-                                           (* k sb!vm:n-byte-bits))))))))
-  (values))
+  (with-fast-read-byte ((unsigned-byte 8) stream)
+    (dotimes (i length)
+      (setf (aref string i)
+            (sb!xc:code-char (fast-read-u-integer 4)))))
+  string)
 \f
 ;;;; miscellaneous fops
 
     #+sb-xc-host
     (read-string-as-bytes *fasl-input-stream* package-name)
     #-sb-xc-host
-    (#!-sb-unicode read-string-as-bytes
-     #!+sb-unicode read-string-as-unsigned-byte-32
-     *fasl-input-stream* package-name)
+    (progn
+      #!-sb-unicode
+      (read-string-as-bytes *fasl-input-stream* package-name)
+      #!+sb-unicode
+      (read-string-as-unsigned-byte-32 *fasl-input-stream* package-name))
     (push-fop-table (find-undeleted-package-or-lose package-name))))
 \f
 ;;;; fops for loading numbers
 (define-cloned-fops (fop-base-string 37) (fop-small-base-string 38)
   (let* ((arg (clone-arg))
          (res (make-string arg :element-type 'base-char)))
-    (read-string-as-bytes *fasl-input-stream* res)
+    (read-base-string-as-bytes *fasl-input-stream* res)
     res))
 
 #!+sb-unicode