[plt-scheme] build-list for large lists

From: David Van Horn (dvanhorn at ccs.neu.edu)
Date: Wed Apr 8 20:05:58 EDT 2009

I was doing some benchmarking of my random-access list package and found 
that its build-list often outperformed scheme/base's build-list function 
for constructing large lists, which seemed curious.

My data representation for a list is a list of complete binary trees, 
and build-list boils down to build-tree, which is defined by recursion 
on the size of the tree.

I thought perhaps the performance boost was due to using recursion 
rather than iteration and reverse as done in scheme/base build-list, so 
I did some comparisons with a recursive definition of build-list, which 
indeed does better on large lists.

Finally, the tree-based version still outperforms both the recursive 
build-list and the iterative build-list for really large lists.  I'm not 
sure why.

Anyway, I thought these numbers might be of interest.


#lang scheme
(require (prefix-in ra: (planet dvanhorn/ralist:1:6)))
(require (prefix-in mz: scheme/base))

(define (my:build-list i f)
   (let recr ([j 0] [i i])
     (cond [(zero? i) empty]
           [else (cons (f j)
                       (recr (add1 j) (sub1 i)))])))

(define id (lambda (i) i))

(define-syntax times
   (syntax-rules ()
     ((times n e)
      (begin (collect-garbage)
             (time (for ([i (in-range n)]) e))))))

(let ((n 500000))
   (times 5 (mz:build-list n id))
   (times 5 (ra:build-list n id))
   (times 5 (my:build-list n id)))

;; cpu time: 5482 real time: 5490 gc time: 5267
;; cpu time: 836 real time: 858 gc time: 76
;; cpu time: 392 real time: 429 gc time: 76

(let ((n 10000000))
   (times 1 (mz:build-list n id))
   (times 1 (ra:build-list n id))
   (times 1 (my:build-list n id)))

;; cpu time: 7241 real time: 7271 gc time: 6367
;; cpu time: 4920 real time: 4959 gc time: 1953
;; cpu time: 5248 real time: 5283 gc time: 3305

Posted on the users mailing list.