*Slightly too significant, since I wrote g incorrectly. This is right: #lang racket
(collect-garbage) (collect-garbage) (collect-garbage) (define as (build-list 1000000 (λ (n) (random 100)))) (define bs (build-list 1000000 (λ (n) (random 100)))) (define (f as bs [acc 0]) (if (or (null? as) (null? bs)) acc (f (rest as) (rest bs) (+ acc (* (first as) (first bs)))))) (time (f as bs)) (collect-garbage) (collect-garbage) (collect-garbage) (define (g as bs) (let g ([as as] [bs bs] [acc 0]) (cond [(or (null? as) (null? bs)) acc] [else (match-define (cons this-a more-as) as) (match-define (cons this-b more-bs) bs) (g more-as more-bs (+ acc (* this-a this-b)))]))) (time (g as bs)) ;; timed in DrRacket w/ debugging ;cpu time: 386 real time: 385 gc time: 45 ;2448129646 ;cpu time: 122 real time: 121 gc time: 0 ;2448129646 -Philip On Thu, Jul 27, 2017 at 8:13 PM, Philip McGrath <phi...@philipmcgrath.com> wrote: > Eliminating the optional argument and using match-define to avoid any > redundant checking on first and rest gets me a significant speedup: > > #lang racket > > (collect-garbage) > (collect-garbage) > (collect-garbage) > > (define as (build-list 1000000 (λ (n) (random 100)))) > (define bs (build-list 1000000 (λ (n) (random 100)))) > > (define (f as bs [acc 0]) > (if (or (null? as) (null? bs)) > acc > (f (rest as) (rest bs) (+ acc (* (first as) (first bs)))))) > > (time (f as bs)) > > (collect-garbage) > (collect-garbage) > (collect-garbage) > > (define (g as bs) > (let g ([as as] > [bs bs] > [acc 0]) > (cond > [(or (null? as) (null? bs)) > acc] > [else > (match-define (cons this-a more-as) > as) > (match-define (cons this-b more-bs) > bs) > (g more-as more-bs (+ acc this-a this-b))]))) > > (time (g as bs)) > > ; timed in DrRacket w/ debugging > ;cpu time: 326 real time: 326 gc time: 0 > ;2451374037 > ;cpu time: 68 real time: 69 gc time: 0 > ;98991285 > > -Philip > > On Thu, Jul 27, 2017 at 8:08 PM, Gustavo Massaccesi <gust...@oma.org.ar> > wrote: > >> Functions with optional arguments are slow. They are expanded to a >> case-lambda and an if. This version with an auxiliary function is >> faster: >> >> >> #lang racket >> >> (define as (build-list 1000000 (λ (n) (random 100)))) >> (define bs (build-list 1000000 (λ (n) (random 100)))) >> >> >> (define (f/opt as bs [acc 0]) >> (if (or (null? as) (null? bs)) >> acc >> (f/opt (rest as) (rest bs) (+ acc (* (first as) (first bs)))))) >> >> (collect-garbage) >> (collect-garbage) >> (collect-garbage) >> (time (f/opt as bs)) >> >> >> (define (f/acc as bs acc) >> (if (or (null? as) (null? bs)) >> acc >> (f/acc (rest as) (rest bs) (+ acc (* (first as) (first bs)))))) >> >> (define (f/no-acc as bs acc) >> (f/acc as bs 0)) >> >> (collect-garbage) >> (collect-garbage) >> (collect-garbage) >> (time (f/no-acc as bs 0)) >> >> ;cpu time: 281 real time: 268 gc time: 0 >> ;2447735069 >> ;cpu time: 94 real time: 93 gc time: 0 >> ;2447735069 >> >> Gustavo >> >> On Thu, Jul 27, 2017 at 10:07 PM, Jon Zeppieri <zeppi...@gmail.com> >> wrote: >> > You can get better performance out of the recursive function by using >> > car/cdr instead of first/rest; first/rest require their arguments to >> > be lists, whereas car/cdr require theirs to be pairs, which is a lot >> > cheaper to check. Also, using an optional argument (in a loop, >> > especially) makes a difference. >> > >> > Even so, for/sum wins, because it uses ops like unsafe-car and >> > unsafe-cdr, which it can do safely, since it first establishes that >> > it's working with a list (and then doesn't have to check again). >> > >> > - Jon >> > >> > On Thu, Jul 27, 2017 at 8:55 PM, Daniel Prager >> > <daniel.a.pra...@gmail.com> wrote: >> >> Revised to collect garbage before each timing shows the recursive >> function >> >> isn't too bad (but not great): >> >> >> >> cpu time: 405 real time: 404 gc time: 0 >> >> 2452578471 >> >> >> >> cpu time: 368 real time: 368 gc time: 0 >> >> 2452578471 >> >> >> >> cpu time: 50 real time: 50 gc time: 0 >> >> 2452578471 >> >> >> >> cpu time: 194 real time: 195 gc time: 75 >> >> 2452578471 >> >> >> >> >> >> Dan >> >> >> >> -- >> >> You received this message because you are subscribed to the Google >> Groups >> >> "Racket Users" group. >> >> To unsubscribe from this group and stop receiving emails from it, send >> an >> >> email to racket-users+unsubscr...@googlegroups.com. >> >> For more options, visit https://groups.google.com/d/optout. >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Racket Users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to racket-users+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.