[racket] Style and Performance question

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Tue May 10 06:03:54 EDT 2011

Robby is right. I fell into the exact-rational-arithmetic trap. Racket "silently" crunched exact fractions for the original version. When I converted it, the type checker asked for something other than x and I realized that I needed to get an inexact in somewhere. "2.0" was the natural place. I even made a mental remark to myself to measure the inexact version but somehow I managed to forget it very quickly last night. -- Matthias



On May 9, 2011, at 11:37 PM, Robby Findler wrote:

> On Mon, May 9, 2011 at 10:25 PM, Sam Tobin-Hochstadt <samth at ccs.neu.edu> wrote:
>> On Mon, May 9, 2011 at 11:19 PM, Robby Findler
>> <robby at eecs.northwestern.edu> wrote:
>>> Even without typed racket, this:
>>> 
>>> (define (my-sqrt y)
>>>  (let loop [(x (/ y 2.0))]
>> 
>>> is much faster than this:
>>> 
>>> (define (my-sqrt y)
>>>  (let loop [(x (/ y 2))]
>> 
>> Yes, this is one of the optimizations TR does.  :)
> 
> It is not a meaning preserving transformation to turn the 2 into a 2.0
> in this function, I don't think.
> 
> Also, Matthias explicitly wrote "2.0" in the tr version. He didn't
> show the other version, but my timing results suggest he wrote "2" in
> the other one (and Patrick certainly did).
> 
>> As to why TR is so much faster on this program: this is exactly the
>> sort of program that TR excels at -- generic arithmetic on floats,
>> which we can turn into fast machine instructions.  You won't find a
>> better case for TR than this, except if you add complex numbers.
> 
> I don't think that this is accurate, Sam.
> 
> This is the difference I see and it is more in line with what I would
> expect given how I think TR inserts unsafe calls, etc.
> 
> [robby at gaoping] ~/git/plt/src/build$ racket ~/tmp-tr.rkt
> cpu time: 187 real time: 221 gc time: 6
> [robby at gaoping] ~/git/plt/src/build$ racket ~/tmp.rkt
> cpu time: 301 real time: 400 gc time: 103
> [robby at gaoping] ~/git/plt/src/build$ cat ~/tmp.rkt
> #lang racket/base
> 
> (define epsilon 1e-7)
> 
> (define (my-sqrt y)
>  (let loop [(x (/ y 2.0))]
>    (let [(error (- y (* x x)))]
>      (if (< (abs error) epsilon)
>          x
>          (loop (+ x (/ error 2 x)))))))
> 
> (define (time-and-compare size count)
>  (define n (build-list size (lambda (_) (random 10))))
>  (collect-garbage) (collect-garbage) (collect-garbage)
>  (define l (time (for ([x (in-range 0 count)])
>                    (for-each my-sqrt n))))
>  (void))
> 
> (time-and-compare 100 2000)
> [robby at gaoping] ~/git/plt/src/build$ cat ~/tmp-tr.rkt
> #lang typed/racket
> 
> (define epsilon 1e-7)
> 
> (: my-sqrt : Natural -> Real)
> (define (my-sqrt y)
>  (let loop [(x (/ y 2.0))]
>    (let [(error (- y (* x x)))]
>      (if (< (abs error) epsilon)
>          x
>          (loop (+ x (/ error 2 x)))))))
> 
> (: time-and-compare : Natural Natural -> Void)
> (define (time-and-compare size count)
>  (define n (build-list size (lambda (_) (random 10))))
>  (collect-garbage) (collect-garbage) (collect-garbage)
>  (define l (time (for ([x (in-range 0 count)])
>                    (for-each my-sqrt n))))
>  (void))
> 
> (time-and-compare 100 2000)




Posted on the users mailing list.