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

Reply via email to