# [racket] (Math) Computing the mean is slow in Typed Racket

Hi Laurent,
2013/2/8 Laurent <laurent.orseau at gmail.com>:
>* (Just a little testing of the exciting new math lib.)
*>*
*>* Is it currently normal that computing the mean of a big list is 10x slower
*>* compared to the (/ (apply + l) (length l)) method?
*>*
*>* The math lib is very recent so I'm not entirely surprised, anyway. Most of
*>* the time seems to be due to GC.
*>*
*>* E.g. (on command line Racket) :
*>* #lang typed/racket
*>*
*>* (require math)
*>*
*>* (: n Integer)
*>* (define n 10000000)
*>* (: l (Listof Integer))
*>* (define l (build-list n (λ(x)(random 100))))
*>*
*>* (: my-mean ((Listof Integer) -> Number))
*>* (define (my-mean l)
*>* (/ (apply + l) (length l)))
*>*
*>* (time (mean l))
*>* (time (my-mean l))
*
Nice catch. Here is the code for mean from:
collects/math/statistics/private/expected-values.rkt
The function handles general sequences and optional weights.
(: mean (case-> ((Sequenceof Real) -> Real)
((Sequenceof Real) (Option (Sequenceof Real)) -> Real)))
(define (mean xs [ws #f])
(cond [ws (let-values ([(xs ws) (sequences->weighted-samples 'mean xs ws)])
(define n (sum ws))
(cond [(zero? n) +nan.0]
[else (/ (sum (map * xs ws)) n)]))]
[else (let ([xs (sequence->list xs)])
(define n (length xs))
(cond [(zero? n) +nan.0]
[else (/ (sum xs) n)]))]))
In this case ws is #f, so we can ignore the first cond-clause,
and concentrate on:
(let ([xs (sequence->list xs)])
(define n (length xs))
(cond [(zero? n) +nan.0]
[else (/ (sum xs) n)]))]))
Here we see why the mean was slow:
[xs (sequence->list xs)]
This copies the list even though xs is a list already.
Try
[xs (if (list? xs) xs (sequence->list xs))])
and see what the new timings are.
--
Jens Axel Søgaard