[racket] Super basic question about strings

From: Neil Van Dyke (neil at neilvandyke.org)
Date: Wed Nov 17 14:13:28 EST 2010

Matthias Felleisen wrote at 11/17/2010 01:48 PM:
> Changing from ~s to ~a makes ALL of our versions almost twice as fast as Neil's. 
> Not using format at all is still the fastest way to go. 
> Functional programming remains better than imperative programming. 

I generally agree with the point about functional programming.

I *have* been seeing superior results in many cases with string ports, 
but part of that might be that most of the work was using the old CGC.

Also, for nontrivial writing procedures that scale to things like disk 
or network I/O of large outputs, I usually implement them to write to 
ports, and then make a convenience wrapper procedure that uses a string 
port to produce a string, for people who want that.

That said, although it pains me deeply to use non-tail-recursion to 
build a potentially huge list and then do an apply on the value, here's 
a functional example that runs in 66% of the time of "alist->string.v5" 
in my tests with the short alist:

(define (alist->string.bl2 alist)
  (apply string-append
         (if (null? alist)
               (let loop ((head (car alist))
                          (tail (cdr alist)))
                 `(,(symbol->string (car head))
                   ,(number->string (cdr head))
                   ,@(if (null? tail)
                         `(" " ,@(loop (car tail) (cdr tail)))))))))

If I had more time, I'd also try making it collect the intermediate 
result list in reverse, to that tail calls could be used.  At least, I'd 
try it if this code were a hotspot.

I'm also now curious whether the string port implementation could be 
sped up at all, perhaps in light of the JIT.


Posted on the users mailing list.