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 <sa...@ccs.neu.edu> > wrote: >> On Mon, May 9, 2011 at 11:19 PM, Robby Findler >> <ro...@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@gaoping] ~/git/plt/src/build$ racket ~/tmp-tr.rkt > cpu time: 187 real time: 221 gc time: 6 > [robby@gaoping] ~/git/plt/src/build$ racket ~/tmp.rkt > cpu time: 301 real time: 400 gc time: 103 > [robby@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@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) _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users