No, not if you mean "deep binding" in the sense of a list that has to be searched to find a parameter value.
At Fri, 16 Aug 2013 05:23:52 -0700, Joe Marshall wrote: > Sounds like Racket is using a "deep binding" strategy rather than "shallow > binding". I expect that SBCL uses shallow. > On Aug 16, 2013 5:10 AM, "Matthew Flatt" <[email protected]> wrote: > > > At Fri, 16 Aug 2013 13:59:55 +0400, Roman Klochkov wrote: > > > > > > I compared parameterize with lexical var > > > ---- > > > > (require rackunit) > > > > (define my-parameter (make-parameter (box 0))) > > > > (time > > > (parameterize ([my-parameter (box 0)]) > > > (for ([x (in-range 10000000)]) > > > (set-box! (my-parameter) > > > (add1 (unbox (my-parameter))))) > > > (check-equal? (unbox (my-parameter)) 10000000))) > > > cpu time: 3578 real time: 3610 gc time: 0 > > > > (time > > > (let ([my-parameter (box 0)]) > > > (for ([x (in-range 10000000)]) > > > (set-box! my-parameter > > > (add1 (unbox my-parameter)))) > > > (check-equal? (unbox my-parameter) 10000000))) > > > cpu time: 47 real time: 47 gc time: 0 > > > ---- > > > > > > 100 times difference! > > > > > > The same experiment with Common Lisp (SBCL): > > > ---- > > > CL-USER> (setf *a* (list 0)) > > > (0) > > > CL-USER> (time (progn (loop :for i :from 0 :below 10000000 > > > :do (setf (car *a*) (+ 1 (car *a*)))) (= (car *a*) > > 10000000))) > > > Evaluation took: > > > 0.063 seconds of real time > > > 0.062500 seconds of total run time (0.062500 user, 0.000000 system) > > > 98.41% CPU > > > 172,464,541 processor cycles > > > 0 bytes consed > > > > > > T > > > CL-USER> (let ((a (list 0))) (time (loop :for i :from 0 :below 10000000 > > > :do (setf (car a) (+ 1 (car a))))) (= (car a) 10000000)) > > > > > > Evaluation took: > > > 0.047 seconds of real time > > > 0.046875 seconds of total run time (0.046875 user, 0.000000 system) > > > 100.00% CPU > > > 132,098,942 processor cycles > > > 0 bytes consed > > > > > > T > > > ---- > > > Only 1.5 times. > > > > > > Is it undesirable to use parameterize as replacement for common lisp > > special > > > variables? What is it designed for then? > > > > Parameters in Racket are grouped together in a an extra layer called a > > "parameterization", which enables capture of the current values of all > > parameters. For example, when a new thread is created in Racket, then > > the new inherits all of the current parameter values from the creating > > thread. A lack of cleverness in that layer is probably the main effect > > on performance in yuor example. > > > > Using a raw, symbol-keyed continuation mark would be closer to a Common > > Lisp special variable, I think. On my machine: > > > > ;; parameter > > > (time > > (parameterize ([my-parameter (box 0)]) > > (for ([x (in-range 10000000)]) > > (set-box! (my-parameter) > > (add1 (unbox (my-parameter))))) > > (check-equal? (unbox (my-parameter)) 10000000))) > > cpu time: 2539 real time: 2537 gc time: 0 > > > > ;; direct > > > (time > > (let ([my-parameter (box 0)]) > > (for ([x (in-range 10000000)]) > > (set-box! my-parameter > > (add1 (unbox my-parameter)))) > > (check-equal? (unbox my-parameter) 10000000))) > > cpu time: 45 real time: 45 gc time: 0 > > > > ;; raw continuation mark: > > > (time > > (let ([my-parameter > > (lambda () > > (continuation-mark-set-first #f 'my-parameter))]) > > (with-continuation-mark > > 'my-parameter > > (box 0) > > (begin > > (for ([x (in-range 10000000)]) > > (set-box! (my-parameter) > > (add1 (unbox (my-parameter))))) > > (check-equal? (unbox (my-parameter)) 10000000))))) > > cpu time: 244 real time: 243 gc time: 0 > > > > That's still a fact of 5 difference. I expect that dynamic binding and > > special variables have played a more prominent role in Common Lisp than > > parameters or even continuation-mark lookup in Racket, and so it would > > make sense that more work has been done in the SBCL to make them fast. > > > > > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > ____________________ Racket Users list: http://lists.racket-lang.org/users

