Date: Thu, 24 Sep 2009 13:48:34 -0700 From: Joe Marshall <jmarsh...@alum.mit.edu>
Has anyone measured the performance difference between smashing the string head and just taking a substring? I'd bet it's a pretty minimal improvement against the background of the other things that happen during I/O. I conducted a thoroughly unscientific comparison whose source code is attached: making a string of length 2^(i + 1), taking a prefix of length 2^i, and then discarding it, repeating the process ten thousand times. Using SUBSTRING becomes slower than SET-STRING-MAXIMUM-LENGTH! when i is about 5. This is in line with SUBSTRING-MOVE-{LEFT,RIGHT}!, actually, which defer to the primitive as soon as the string's length exceeds 2^5. Winning on just GC time starts to happen when i is about 10. (Your mileage may vary, of course. I ran this code compiled, by the way.) So how about the following definition? (define (string-head! string end) (guarantee-string string 'STRING-HEAD!) (guarantee-substring-end-index end (string-length string) 'STRING-HEAD!) (if (and (fix:< end (string-length string)) (or (fix:< end 32) ;32 computed by science (ha!). (begin ;; Some implementations of the microcode don't ;; support SET-STRING-MAXIMUM-LENGTH!. In this case, ;; defer to %STRING-HEAD. ((ucode-primitive set-string-maximum-length! 2) string end) (not (fix:= end (string-maximum-length string)))))) (%string-head string end) string))
(declare (usual-integrations)) (define (test-substring-string-head prefix-length total-length) (let loop ((i 0)) (if (fix:< i 10000) (begin (substring (make-string total-length) 0 prefix-length) (loop (fix:+ i 1)))))) (define-syntax ucode-primitive (sc-macro-transformer (lambda (form environment) environment ;environment (apply make-primitive-procedure (cdr form))))) (define (test-maxlength-string-head prefix-length total-length) (let loop ((i 0)) (if (fix:< i 10000) (begin ((ucode-primitive set-string-maximum-length! 2) (make-string total-length) prefix-length) (loop (fix:+ i 1)))))) (define (compare-em) (define (run-test name procedure) (newline) (write-string ";** ") (pp name) (do ((i 0 (fix:+ i 1))) ((fix:>= i 20)) ;; Sorry for the ugly output. SHOW-TIME doesn't like having a ;; prefix on each line. (fresh-line) (pp i) (gc-flip) (show-time (lambda () (procedure (fix:lsh 1 i) (fix:lsh 1 (fix:+ i 1)))))) (print-gc-statistics)) (run-test 'SUBSTRING test-substring-string-head) (run-test 'SET-STRING-MAXIMUM-LENGTH! test-maxlength-string-head))
_______________________________________________ MIT-Scheme-devel mailing list MIT-Scheme-devel@gnu.org http://lists.gnu.org/mailman/listinfo/mit-scheme-devel