Marc,

just to ensure I got your point. You say that one could create a string-port more than 20 times faster than Gambit's built-in string ports. I'm interested in the reason - is this because:

a) If one writes one in scheme code, Gambit may perform function inlining?
b) You presume that the string-port implementation one writes does not need to be thread-safe, within the context of Gambit's threading system, as is Gambit's built in string port?

Any more reasons?

Also, what further reasons do you see as to why a SSAX-SXML XML to SXML deserialization that takes 3 seconds in Java takes 50 seconds in Gambit? I mean, in general, Gambit code is a lot faster than Java, so this is an exception to the general rule.

Can you further describe how to create a complete port implementation, such as a string port or a gzip port?

M

2008/8/16 Marc Feeley <feeley@iro.umontreal.ca>
If you are really into optimizing the I/O, I suggest you implement
your own special purpose string-port I/O layer.  Basically you
redefine read-char to read from a string.  The code below shows that
this can be over 20 times faster than Gambit's built-in string ports.
The main reasons for the difference are function inlining and locking
(to support multithreading).

(define (convoluted-string-length1 str) ;; uses standard string ports
  (declare (standard-bindings) (fixnum) (not safe))
  (let ((port (open-input-string str)))
    (let loop ((i 0))
      (let ((c (read-char port)))
        (if (char? c)
            (loop (+ i 1))
            i)))))

(define-macro (macro-open-input-string str)
  `(let ((str ,str))
     (declare (standard-bindings) (fixnum) (not safe))
     (cons str 0)))

(define-macro (macro-read-char my-port)
  `(let ((my-port ,my-port))
     (declare (standard-bindings) (fixnum) (not safe))
     (let ((str (car my-port))
           (pos (cdr my-port)))
       (if (< pos (string-length str))
           (let ((c (string-ref str pos)))
             (set-cdr! my-port (+ 1 pos))
             c)
           #!eof))))

(define-macro (open-input-string str) `(macro-open-input-string ,str))
(define-macro (read-char port) `(macro-read-char ,port))

;; insert your code after this point, for example:

(define (convoluted-string-length2 str) ;; uses "fast" string ports
  (declare (standard-bindings) (fixnum) (not safe))
  (let ((port (open-input-string str)))
    (let loop ((i 0))
      (let ((c (read-char port)))
        (if (char? c)
            (loop (+ i 1))
            i)))))

(define (test)
  (let ((s (make-string 4000000 #\!)))
    (pretty-print (time (convoluted-string-length1 s)))
    (pretty-print (time (convoluted-string-length2 s)))))

(test)

;; (time (convoluted-string-length1 s))
;;     704 ms real time
;;     703 ms cpu time (661 user, 42 system)
;;     1 collection accounting for 50 ms real time (32 user, 19 system)
;;     36023288 bytes allocated
;;     no minor faults
;;     no major faults
;; 4000000
;; (time (convoluted-string-length2 s))
;;     26 ms real time
;;     25 ms cpu time (25 user, 0 system)
;;     no collections
;;     24 bytes allocated
;;     no minor faults
;;     no major faults
;; 4000000

_______________________________________________
Gambit-list mailing list
Gambit-list@iro.umontreal.ca
https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list