Programming

(Racket) Sequences

steloflute 2013. 9. 3. 22:44

http://docs.racket-lang.org/reference/sequences.html#%28tech._sequence%29


The sequence datatype overlaps with many other datatypes. Among built-in datatypes, the sequence datatype includes the following:

An exact number k that is a non-negative integer acts as a sequence similar to (in-range k), except that k by itself is not a stream.



http://learnxinyminutes.com/docs/racket/

(for ([i 10])
  (printf "i=~a\n" i)) ; => i=0, i=1, ...
(for ([i (in-range 5 10)])
  (printf "i=~a\n" i)) ; => i=5, i=6, ...


http://docs.racket-lang.org/guide/for.html#%28part._for-performance%29


11.10 Iteration Performance

Ideally, a for iteration should run as fast as a loop that you write by hand as a recursive-function invocation. A hand-written loop, however, is normally specific to a particular kind of data, such as lists. In that case, the hand-written loop uses selectors like car and cdr directly, instead of handling all forms of sequences and dispatching to an appropriate iterator.

The for forms can provide the performance of hand-written loops when enough information is apparent about the sequences to iterate. Specifically, the clause should have one of the following fast-clause forms:

  fast-clause = [id fast-seq]
  | [(id) fast-seq]
  | [(id id) fast-indexed-seq]
  | [(id ...) fast-parallel-seq]
  fast-seq = (in-range expr)
  | (in-range expr expr)
  | (in-range expr expr expr)
  | (in-naturals)
  | (in-naturals expr)
  | (in-list expr)
  | (in-vector expr)
  | (in-string expr)
  | (in-bytes expr)
  | (in-value expr)
  | (stop-before fast-seq predicate-expr)
  | (stop-after fast-seq predicate-expr)
  fast-indexed-seq = (in-indexed fast-seq)
  | (stop-before fast-indexed-seq predicate-expr)
  | (stop-after fast-indexed-seq predicate-expr)
  fast-parallel-seq = (in-parallel fast-seq ...)
  | (stop-before fast-parallel-seq predicate-expr)
  | (stop-after fast-parallel-seq predicate-expr)

Examples:

> (time (for ([i (in-range 100000)])
          (for ([elem (in-list '(a b c d e f g h))]) ; fast
            (void))))

cpu time: 1 real time: 2 gc time: 0


> (time (for ([i (in-range 100000)])
          (for ([elem '(a b c d e f g h)])           ; slower
            (void))))

cpu time: 35 real time: 35 gc time: 0


> (time (let ([seq (in-list '(a b c d e f g h))])
          (for ([i (in-range 100000)])
            (for ([elem seq])                        ; slower
              (void)))))

cpu time: 41 real time: 42 gc time: 0


The grammars above are not complete, because the set of syntactic patterns that provide good performance is extensible, just like the set of sequence values. The documentation for a sequence constructor should indicate the performance benefits of using it directly in a for clause.