[racket] performance of iteration through a vector

From: Matthew Butterick (mb at mbtype.com)
Date: Sat Aug 30 21:18:13 EDT 2014

Usually you'll get the best performance from `for` loops by using the in-* iterators. 
In this case, you can use `in-vector` [1], which on my machine is faster:

(let ((t (current-inexact-milliseconds))
      (sum 0))
  (for ((j (in-range 1000000)))
    (for ((v (in-vector vec)))
      (set! sum (+ sum v))))
  (displayln (/ (- (current-inexact-milliseconds) t) 1000.0)))

I assume this is a synthetic example, but you can also improve performance by using appropriate versions of `for`. This is faster than the last one:

(let ((t (current-inexact-milliseconds)))
  (for*/fold ([sum 0])([j (in-range 1000000)][v (in-vector vec)])
    (+ sum v))
  (displayln (/ (- (current-inexact-milliseconds) t) 1000.0)))

And this is faster still:

(let ((t (current-inexact-milliseconds)))
  (for*/sum ([j (in-range 1000000)][v (in-vector vec)])
    v)
  (displayln (/ (- (current-inexact-milliseconds) t) 1000.0)))


[1] http://docs.racket-lang.org/reference/sequences.html?q=in-vector#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._in-vector%29%29


On Aug 30, 2014, at 3:54 PM, Dmitry Pavlov <dpavlov at ipa.nw.ru> wrote:

> Hello,
> 
> Consider the following program:
> 
> (define n 100)
> (define vec (for/vector ((i (in-range n))) i))
> 
> (let ((t (current-inexact-milliseconds))
>       (sum 0))
>   (for ((j (in-range 1000000)))
>     (for ((i (in-range n)))
>       (set! sum (+ sum (vector-ref vec i)))))
>   (displayln (/ (- (current-inexact-milliseconds) t) 1000.0)))
>   
> (let ((t (current-inexact-milliseconds))
>       (sum 0))
>   (for ((j (in-range 1000000)))
>     (for ((v vec))
>       (set! sum (+ sum v))))
>   (displayln (/ (- (current-inexact-milliseconds) t) 1000.0)))
> 
> 
> On my system (64-bit linux, Racket 6.1.0.2), it gives the following result:
> 
> 1.016682861328125
> 6.3261611328125
> 
> 
> So we can make a conclusion that (for ((v vec)) ...) is
> 6x slower than (for ((i (in-range n))) ... (vector-ref vec i) ...)
> Is it normal? Would you advise to use the explicit (vector-ref)
> when performance matters?
> 
> Best regards
> 
> Dmitry
> 
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users




On Aug 30, 2014, at 3:54 PM, Dmitry Pavlov <dpavlov at ipa.nw.ru> wrote:

> Hello,
> 
> Consider the following program:
> 
> (define n 100)
> (define vec (for/vector ((i (in-range n))) i))
> 
> (let ((t (current-inexact-milliseconds))
>       (sum 0))
>   (for ((j (in-range 1000000)))
>     (for ((i (in-range n)))
>       (set! sum (+ sum (vector-ref vec i)))))
>   (displayln (/ (- (current-inexact-milliseconds) t) 1000.0)))
>   
> (let ((t (current-inexact-milliseconds))
>       (sum 0))
>   (for ((j (in-range 1000000)))
>     (for ((v vec))
>       (set! sum (+ sum v))))
>   (displayln (/ (- (current-inexact-milliseconds) t) 1000.0)))
> 
> 
> On my system (64-bit linux, Racket 6.1.0.2), it gives the following result:
> 
> 1.016682861328125
> 6.3261611328125
> 
> 
> So we can make a conclusion that (for ((v vec)) ...) is
> 6x slower than (for ((i (in-range n))) ... (vector-ref vec i) ...)
> Is it normal? Would you advise to use the explicit (vector-ref)
> when performance matters?
> 
> Best regards
> 
> Dmitry
> 
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140830/1a5bf544/attachment.html>

Posted on the users mailing list.