Hi Mark!
Do you have any advice to optimize it without disable GC temperaly? Or the
only way is to change a better GC?

2017年6月10日 12:28,"Mark H Weaver" <m...@netris.org>写道:

> Stefan Monnier <monn...@iro.umontreal.ca> writes:
>
> >>   (define (map f l)
> >>     (if (pair? l)
> >>         (cons (f (car l))
> >>               (map f (cdr l)))
> >>         '()))
> >>
> >> whereas we used to have to write code like this in order to support long
> >> lists without overflowing the stack:
> >>
> >>   (define (map f l)
> >>     (let loop ((l l) (out '()))
> >>       (if (pair? l)
> >>           (loop (cdr l) (cons (f (car l)) out))
> >>           (reverse out))))
> >
> > Ignoring stack usage, is the first version faster or slower than the
> second?
> > [ Or is the speed difference negligible?  ]
>
> I don't have time to perform proper benchmarks, but some admittedly
> inadequate measurements on my Thinkpad X200 suggest that the first
> version is about 1.5% faster, mainly because it makes a lot less work
> for the GC.  See below for details of what I did.
>
> > How 'bout using a side-effecting `reverse!` (like Lisp's nreverse)?
>
> We can't do that, because in the presence of first-class continuations
> where the 'f' passed to map may return more than once, using mutation to
> build the result list will change the result for some programs.  Both
> modern scheme standards (R6RS and R7RS) explicitly specify that "If
> multiple returns occur from map, the values returned by earlier returns
> are not mutated".
>
>       Mark
>
>
> mhw@jojen ~$ guile
> GNU Guile 2.2.2
> Copyright (C) 1995-2017 Free Software Foundation, Inc.
>
> Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
> This program is free software, and you are welcome to redistribute it
> under certain conditions; type `,show c' for details.
>
> Enter `,help' for help.
> scheme@(guile-user)> (define (map1 f l) (if (pair? l) (cons (f (car l))
> (map f (cdr l))) '()))
> scheme@(guile-user)> (define (map2 f l) (let loop ((l l) (out '())) (if
> (pair? l) (loop (cdr l) (cons (f (car l)) out)) (reverse out))))
> scheme@(guile-user)> (define var #f)
> scheme@(guile-user)> (define test-list (iota 100000))
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map1 1+ test-list)) (loop (- i 1))))
> ;; 13.121194s real time, 14.072380s run time.  2.346036s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map1 1+ test-list)) (loop (- i 1))))
> ;; 13.006867s real time, 13.940452s run time.  2.263353s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map1 1+ test-list)) (loop (- i 1))))
> ;; 13.079656s real time, 13.946879s run time.  2.197271s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map2 1+ test-list)) (loop (- i 1))))
> ;; 13.029591s real time, 15.312230s run time.  5.601020s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map2 1+ test-list)) (loop (- i 1))))
> ;; 13.041985s real time, 15.306287s run time.  5.581253s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map2 1+ test-list)) (loop (- i 1))))
> ;; 12.003391s real time, 13.421369s run time.  3.662504s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map2 1+ test-list)) (loop (- i 1))))
> ;; 11.993404s real time, 13.367805s run time.  3.496328s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map2 1+ test-list)) (loop (- i 1))))
> ;; 11.964659s real time, 13.362942s run time.  3.544227s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map1 1+ test-list)) (loop (- i 1))))
> ;; 12.619559s real time, 13.153612s run time.  1.471917s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map1 1+ test-list)) (loop (- i 1))))
> ;; 12.600161s real time, 13.136094s run time.  1.476574s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map1 1+ test-list)) (loop (- i 1))))
> ;; 12.584059s real time, 13.142257s run time.  1.478289s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map1 1+ test-list)) (loop (- i 1))))
> ;; 12.626346s real time, 13.146946s run time.  1.466499s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map2 1+ test-list)) (loop (- i 1))))
> ;; 12.009064s real time, 13.361389s run time.  3.690290s spent in GC.
> scheme@(guile-user)> ,time (let loop ((i 1000)) (when (positive? i) (set!
> var (map2 1+ test-list)) (loop (- i 1))))
> ;; 11.970217s real time, 13.317716s run time.  3.352065s spent in GC.
> scheme@(guile-user)>
>
> Here are the 4 best times for each procedure:
>
> map1:
> ;; 12.619559s real time, 13.153612s run time.  1.471917s spent in GC.
> ;; 12.600161s real time, 13.136094s run time.  1.476574s spent in GC.
> ;; 12.584059s real time, 13.142257s run time.  1.478289s spent in GC.
> ;; 12.626346s real time, 13.146946s run time.  1.466499s spent in GC.
>
> averages of 4 best times:
> ;; 12.607531s real time, 13.144727s run time.  1.473320s spent in GC.
>
>
> map2:
> ;; 12.009064s real time, 13.361389s run time.  3.690290s spent in GC.
> ;; 11.993404s real time, 13.367805s run time.  3.496328s spent in GC.
> ;; 11.964659s real time, 13.362942s run time.  3.544227s spent in GC.
> ;; 11.970217s real time, 13.317716s run time.  3.352065s spent in GC.
>
> averages of 4 best times:
> ;; 11.984336s real time, 13.352463s run time.  3.520728s spent in GC.
>
>

Reply via email to