`first` and `rest` need to check if the input is a list (a linear-time
but memoized test), whereas `car` and `cdr` check only if the inputs
are `pair?`s, and match-define uses unsafe operations, doing the pair
check only once.

I see from raco demod that match-define does not generate very
beautiful code, which leads me to this version (which is what I think
match-define should have expanded into). It seems to be about 4x
faster on my computer.

#lang racket
(require racket/unsafe/ops)
(define (as)
  (build-list 1000000 (λ (n) (random 100))))
(define (bs)
  (build-list 1000000 (λ (n) (random 100))))

(define (z as 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)
     (z more-as more-bs (+ acc (* this-a this-b)))]))

(let ([as (as)]
      [bs (bs)])
  (collect-garbage)
  (collect-garbage)
  (collect-garbage)
  (time (for ([i (in-range 10)])
          (z as bs))))

(define (z2 as bs [acc 0])
  (cond
    [(or (null? as) (null? bs))
     acc]
    [else
     (define this-a (car as))
     (define more-as (unsafe-cdr as))
     (define this-b (car bs))
     (define more-bs (unsafe-cdr bs))
     (z2 more-as more-bs (+ acc (* this-a this-b)))]))

(let ([as (as)]
      [bs (bs)])
  (collect-garbage)
  (collect-garbage)
  (collect-garbage)
  (time (for ([i (in-range 10)])
          (z2 as bs))))



Robby

On Thu, Jul 27, 2017 at 8:27 PM, Philip McGrath
<phi...@philipmcgrath.com> wrote:
> `match-define` seems to be the real source of the speedup for me:
>
> #lang racket
>
> (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))))))
>
> (let ([as (as)]
>       [bs (bs)])
>   (collect-garbage)
>   (collect-garbage)
>   (collect-garbage)
>   (time (f as bs)))
>
>
>
> (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)))])))
>
>
> (let ([as (as)]
>       [bs (bs)])
>   (collect-garbage)
>   (collect-garbage)
>   (collect-garbage)
>   (time (g as bs)))
>
> (collect-garbage)
> (collect-garbage)
> (collect-garbage)
>
> (define (z as 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)
>      (z more-as more-bs (+ acc (* this-a this-b)))]))
>
> (let ([as (as)]
>       [bs (bs)])
>   (collect-garbage)
>   (collect-garbage)
>   (collect-garbage)
>   (time (z as bs)))
>
> ; timed at the command line
> ;cpu time: 242 real time: 241 gc time: 0
> ;2452993452
> ;cpu time: 21 real time: 21 gc time: 0
> ;2450414634
> ;cpu time: 22 real time: 22 gc time: 0
> ;2450010495
>
> -Philip
>
> On Thu, Jul 27, 2017 at 8:22 PM, Matthias Felleisen <matth...@ccs.neu.edu>
> wrote:
>>
>>
>> On Jul 27, 2017, at 9:18 PM, Matthew Flatt <mfl...@cs.utah.edu> wrote:
>>
>> I don't think optional arguments are all that slow.
>>
>>
>>
>> This isn’t just Matthew’s opinion. Vincent’s feature-specific profiler
>> could not detect a significant impact of optional or keyword arguments. (See
>> Compiler Construction paper, London 2014 I think)
>>
>> --
>> 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.

Reply via email to