shhyou helped me figure this out; it was really my fault, as I was generating a new set!-transformer each time through the loop, instead of a call to a single transformer.
https://gist.github.com/shhyou/ff5366e8469d4da8f54d262a52744f30#file-bind-it-rkt Fell in a standard macro trap. -- William J. Bowman On Thu, Mar 10, 2022 at 08:49:46PM -0800, 'William J. Bowman' via Racket Developers wrote: > I've extracted a piece of a language implementation here (also attached) > https://gist.github.com/wilbowma/87d7e18718e08968cc4b2d003efbff2b > > It provides two implementations of a little language that provides an > unbounded > number of implicit global mutable variables. > I decided to bind the first 1000 of them because I figure no user would > generate > that many, instead of doing anything clever. > > One method uses `let-syntax` and implements these variables with set! > transformers, and the other just binds the variables with `let`. > > It seems the version that uses `let-syntax` runs in time directly proportional > to the number of these variables I decide to bind, i.e., the number of macros > I > introduce via `let-syntax`; about 1ms per variable bound, regardless of > whether > the macros are ever used. > > This behaviour surprised me a lot. Is this expected? > > -- > William J. Bowman > > -- > You received this message because you are subscribed to the Google Groups > "Racket Developers" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/racket-dev/YirU6gt5MxSnLcvf%40williamjbowman.com. > #lang racket > (require (for-syntax racket/syntax)) > > #| > 1,000 fvars; let-syntax implementation > cpu time: 1162 real time: 1165 gc time: 156 > > 10,000 fvars; let-syntax implementation > cpu time: 10928 real time: 10964 gc time: 1374 > > 1,000 fvars; let implementation > cpu time: 20 real time: 20 gc time: 3 > > 10,000 fvars; let implementation > cpu time: 225 real time: 225 gc time: 54 > |# > > (begin-for-syntax > (define current-fvars (make-parameter 10000)) > > (define (bind-fvars s n tail) > #`(let-syntax > #,(for/list ([i (in-range 0 n)]) > (with-syntax ([fvar (syntax-local-introduce (format-id #f > "fv~a" i))] > [offset i] > [stack s]) > #`[fvar (make-set!-transformer > (lambda (stx) > (syntax-case stx () > [(set! id v) > #`(vector-set! stack offset v)] > [id (identifier? #'id) > #`(vector-ref stack offset)])))])) > #,tail))) > > (define-syntax (my-module stx) > (syntax-case stx () > [(_ e ...) > (with-syntax ([s #'stack]) > #`(let ([s (make-vector #,(current-fvars) (void))]) > #,(bind-fvars #'s (current-fvars) #`(begin e ...))))])) > > (define-namespace-anchor a) > > (displayln "1,000 fvars; let-syntax implementation") > > (time > (eval > '(begin > (begin-for-syntax > (current-fvars 1000)) > (my-module > (set! fv0 8) > (set! fv1 8) > (+ fv0 fv1))) > (namespace-anchor->namespace a))) > > (displayln "10,000 fvars; let-syntax implementation") > > (time > (eval > '(begin > (begin-for-syntax > (current-fvars 10000)) > (my-module > (set! fv0 8) > (set! fv1 8) > (+ fv0 fv1))) > (namespace-anchor->namespace a))) > > (define-for-syntax (bind-fvars2 n tail) > #`(let #,(for/list ([i (in-range 0 n)]) > (with-syntax ([fvar (syntax-local-introduce (format-id #f "fv~a" > i))]) > #`[fvar (void)])) > #,tail)) > > (define-syntax (my-module2 stx) > (syntax-case stx () > [(_ e ...) > (bind-fvars2 (current-fvars) #`(begin e ...))])) > > ;; expansion time increases with the number of let bindings, but not nearly > as bad > ;; expansion time seems to be 1ms per fvar, i.e., per let-syntax? > > (displayln "1,000 fvars; let implementation") > > (time > (eval > '(begin > (begin-for-syntax > (current-fvars 1000)) > (my-module2 > (set! fv0 8) > (set! fv1 8) > (+ fv0 fv1))) > (namespace-anchor->namespace a))) > > (displayln "10,000 fvars; let implementation") > (time > (eval > '(begin > (begin-for-syntax > (current-fvars 10000)) > (my-module2 > (set! fv0 8) > (set! fv1 8) > (+ fv0 fv1))) > (namespace-anchor->namespace a))) -- You received this message because you are subscribed to the Google Groups "Racket Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-dev/YisAyqG3vbsosdna%40williamjbowman.com.
