Sorry, there was a bug in ssax#read-char, a corrected version is included here. There doesn't seem to be a short and easily identifiable "fast-path" in ##write-char, so I just defined ssax#write-char, which is a copy of ##write-char, and defined write-char in terms of it in ssax-sxml.scm.
Pretty strange that the tests in test-sxml.scm passed ...
I ran Marc's example of "build-your-own" string ports on my machine and got:
frying-pan:~/programs/gambc-v4_2_3/ssax-sxml> gsi test-io-3 (time (convoluted-string-length1 s)) 420 ms real time 420 ms cpu time (400 user, 20 system) 1 collection accounting for 17 ms real time (12 user, 4 system) 40016080 bytes allocated 8913 minor faults no major faults 4000000 (time (convoluted-string-length2 s)) 13 ms real time 12 ms cpu time (12 user, 0 system) no collections 32 bytes allocated no minor faults no major faults 4000000
Pretty convincing. I then ran
(define (convoluted-string-length2 str) (let ((port (open-input-string str))) (let loop ((i 0)) (let ((c (read-char port))) (if (char? c) (loop (+ i 1)) i)))))
(define (convoluted-string-length3 port) (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-length2 s))) (let ((port (open-input-string s))) (pretty-print (time (convoluted-string-length3 port))) )))
(test)
with the prefix I made for ssax-sxml.scm and got
frying-pan:~/programs/gambc-v4_2_3/ssax-sxml> gsi test-io (time (convoluted-string-length2 s)) 121 ms real time 124 ms cpu time (112 user, 12 system) 1 collection accounting for 17 ms real time (12 user, 4 system) 40016080 bytes allocated 8912 minor faults no major faults 4000000 (time (convoluted-string-length3 port)) 74 ms real time 76 ms cpu time (76 user, 0 system) no collections -16 bytes allocated no minor faults no major faults 4000000
So open-input-string on a length 4000000 string takes 50ms and allocates 40016080 bytes.
I wanted to test the effects of these changes on the "Gambit Benchmarks", so I added the ssax-sxml.scm prefix to prefix-gambit.scm and ran
./bench -s r6rs-fixflo-unsafe gambit 'cat compiler slatex tail wc dynamic sum1'
all the benchmarks that contain read-char, peek-char, write-char, or eof-object?. Here are the results, first the cputime without the local i/o procedures, then with:
cat: 880 ms 160 ms compiler: 824 ms 820 ms slatex: 356 ms 232 ms tail: 692 ms 380 ms wc: 400 ms 100 ms dynamic: 732 ms 696 ms sum1: 880 ms 896 ms
Judging from
http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php/Gambit_benchmarks
and
http://www.ccs.neu.edu/home/will/Twobit/benchmarksFakeR6Linux.html
this compilation strategy of adding local versions of read-char, write-char, and peek-char, which I outline back in February 2007,
https://webmail.iro.umontreal.ca/pipermail/gambit-list/2007-February/001140....
would allow gambit to improve in the heavy-duty character-oriented benchmarks cat, wc, tail, and slatex.
Brad