[racket-dev] Speeding up sequence->list

From: Neil Toronto (neil.toronto at gmail.com)
Date: Mon Feb 11 13:17:09 EST 2013

The performance of `sequence->list' came up on this thread:

   http://thread.gmane.org/gmane.comp.lang.racket.user/16384

`sequence->list' uses the sequence API to make a copy of its input. This 
can dominate the running time of functions that look like this:

   (define (f xs)
     (let ([xs  (sequence->list xs)])
       ... simple O(n) computation using xs ...))

Also, it seems wasteful to make a copy if `xs' is already a list.

I'd like to change the definition of `sequence->list' from this:

   (define (sequence->list s)
     (for/list ([v s]) v))

to this, to handle the two most common sequences specially:

   (define (my-sequence->list s)
     (cond [(list? s)  s]
           [(vector? s)  (vector->list s)]
           [else  (for/list ([v s]) v)]))

For vectors, I measure a 3x speedup. For lists, it's of course O(1).

It's a semantic change, but I can't imagine anyone relying on this fact:

   (not (eq? xs (sequence->list xs)))

If someone does, [(list? s)  (map values s)] would preserve that fact, 
and is 3x faster in my measurements.

Thoughts?

Neil ⊥

Posted on the dev mailing list.