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