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 racket-dev+unsubscr...@googlegroups.com. > 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 racket-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-dev/YisAyqG3vbsosdna%40williamjbowman.com.