[flexi-streams-devel] New release 0.9.0

Anton Vodonosov vodonosov at mail.ru
Wed Dec 27 20:54:07 UTC 2006


Hi Edi,

Instead of creating a class for each external format
in order to optimize STREAM-READ-CHAR, we
can just take all decision making code out from
STREAM-READ-CHAR to (SETF FLEXI-STREAM-EXTERNAL-FORMAT).

Example of how it may be implemented in the bottom
of the letter (only character encoding handling is
refactored for this demonstration, newline encoding
is leaved unchanged).

I've tested it on clisp 2.41 on my Windows machine.

Function FOO from the testbench code you posted to

 http://thread.gmane.org/gmane.lisp.steel-bank.general/1400/
handles ntoskrnl.exe file with different
flexi-streams versions as follows:

8.0 - 151 sec
9.0 - 40 sec
8.0 with my changes - 79 sec (note, only character encoding handling was
    optimized here)


Regards,
-Anton


(defclass flexi-input-stream (flexi-stream fundamental-binary-input-stream
                                           
fundamental-character-input-stream)
  (
    ....
(get-char-code-func :initform nil))
...
)


(defmethod stream-read-char ((stream flexi-input-stream))
...
      ;(let ((char-code (get-char-code)))
      (let ((char-code (funcall (slot-value stream 'get-char-code-func) 
stream)))
...
   )

#-:lispworks
(defmethod initialize-instance :after ((flexi-stream flexi-input-stream) 
&rest initargs)
  (setf (slot-value flexi-stream 'get-char-code-func)
    (create-char-reader flexi-stream
                (external-format-name (flexi-stream-external-format 
flexi-stream)))))

(defmethod (setf flexi-stream-external-format) :after (new-value (stream 
flexi-input-stream))
  (setf (slot-value stream 'get-char-code-func)
    (create-char-reader stream (external-format-name new-value))))

(defun create-char-reader (stream external-format-name)
  (format t "create-char-reader, stream: ~A, external-format-name: ~A~%"
      stream external-format-name)
  (cond ((ascii-name-p external-format-name)
     #'(lambda (stream) (read-char-8-bit stream +ascii-table+)))
    ((koi8-r-name-p external-format-name)
     #'(lambda (stream)(read-char-8-bit stream +koi8-r-table+)))
    ((iso-8859-name-p external-format-name)
     (let ((table (cdr (assoc external-format-name +iso-8859-tables+
                  :test #'eq))))
       #'(lambda (stream)(read-char-8-bit stream table))))
    ((code-page-name-p external-format-name)
     (let ((table (cdr (assoc (external-format-id external-format)
                  +code-page-tables+))))
       #'(lambda (stream) (read-char-8-bit stream table))))
    (t (case external-format-name
         (:utf-8 #'read-char-utf-8)
         (:utf-16 #'read-char-utf-16)
         (:utf-32 #'read-char-utf-32)))))




More information about the Flexi-streams-devel mailing list