[racket] string-strip

From: Neil Van Dyke (neil at neilvandyke.org)
Date: Tue Dec 27 14:56:07 EST 2011

Tangential comment: These string operations are convenient to have 
around, and they can be expedient, but composing with them can make for 
inefficient evaluation.

For example, my first attempt to implement "string->number" (after 
briefly considering just using "read"), was 17 times faster in a 
shootout on my computer, compared to the one that was built using 
"string-strip" and other string operations.  (It also helped that I used 
Racket regexps rather than pregexps.)

(define (string->number-list/mk2 str)
   (let loop ((start 0))
     (cond ((regexp-match-positions #rx"^[ \t\r\n\f]*([0-9]+(?:[0-9]+)?)"
            => (lambda (m)
                 (let* ((range (cadr m))
                        (end   (cdr range)))
                   (cons (string->number (substring str
                                                    (car range)
                                                    (cdr range)))
                         (loop end)))))
           (else (if (regexp-match? #rx"^[ \t\r\n\f]*$" str start)
                     (error 'string->number-list
                            "could not parse string ~S at start position ~S"

If I was writing performance-sensitive code, I would also see whether a 
procedure that scanned a character at a time, and didn't need 
"string->number", was faster.

As everyone knows, if the code is not performance-sensitive, do whatever 
is easiest to develop in a correct and maintainable way.  But, when 
performance matters -- such as in code that takes a significant 
percentage of time in serving a HTTP request, or is in a PLaneT package 
that other people might use in performance-sensitive context -- we also 
have to think about algorithmic efficiency, as well as costs specific to 
the language implementation.


Posted on the users mailing list.