[racket] Super basic question about strings
For new students, I would show them examples like Eli and Matthias did.
For production work, I usually build up strings using string ports.
Compared to various ways of building lists and doing "string-append", or
to simply doing lots of incremental "string-append" or "format", using a
string port usually permits more tail calls, and sometimes reduces
allocations or otherwise inefficient calls. (Note that I assume that
the string port implementation itself is very efficient internally.)
For example, a first attempt using string ports, without performance tuning:
(define (alist->string alist)
(if (null? alist)
""
(let ((os (open-output-string)))
(let loop ((alist alist))
(write (caar alist) os)
(write-char #\= os)
(write (cdar alist) os)
(if (null? (cdr alist))
(begin0 (get-output-string os)
(close-output-port os))
(begin (write-char #\space os)
(loop (cdr alist))))))))
The string ports example is a lot more verbose than Matthias's
string-join/map/format example, but in a couple quick profiles of
100,000 iterations just now, on an alist of only 5 elements, the string
ports example ran in 74%-76% of the time. In a couple additional
profiles, this performance edge seems to increase with the length of the
alist and/or length of the output string.
For programs that are sufficiently fast, this particular performance
edge is insignificant. But when you're building large production
systems, I've seen attention to grungy low-level performance details in
Racket result in boosts of 2x, 10x, 50x... That makes a big difference
when you want your Web site to respond in a fraction of a second under
load or you're buying/renting application servers.
--
http://www.neilvandyke.org/