On Fri, May 1, 2020 at 10:02 PM Arthur A. Gleckler <s...@speechcode.com> wrote:
> Now back to the performance problems. > I'm consistently finding that code that calls read gets slower and slower until I call gc-flip, when it suddenly becomes faster again, but only for a while. Setting *parser-associate-positions?* to #f doesn't change this behavior, but that was my first guess. Using the profiler shows what appears to be a hot spot in eqv?, with a lot of frames involving weak pairs. After a GC, that hot spot goes from 273 samples to 2. Stack sampler output attached. Replacing the reader's make-shared-objects with a procedure that always returns the same hash table eliminates the problem. So it appears that the construction of the table is a bottleneck. Just calling make-strong-eqv-hash-table in a loop 1000 times isn't slow (80ms), so it does appear to increase GC pressure over time. I'm not sure how to proceed. Suggestions welcome. Thanks.
1 ]=> (begin (with-stack-sampling 10 (lambda () (do ((i 0 (1+ i))) ((= i 1000)) (with-input-from-string "foo" read)))) unspecific) ;Stack-sampling... done ; ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> (runtime dynamic), parameterize* ;-> (runtime dynamic), (lambda) ;-> (runtime dynamic), create-binding ;-> (runtime hash-table), (lambda), (let), make-method:get, method:get ;-> (runtime hash-table), compute-address-hash, (lambda), loop ; evaluating ;(key-hash key (vector-length (... table))) ; for ### in ;(let ((hash |###|)) (if (... table) (begin ... ...) hash)) ;-> (runtime hash-table), protected-key-hash, (lambda) ; evaluating ;(key-hash key modulus) ; for ### in ;(let ((hash |###|)) ; (if (not ...) (error:wrong-type-datum hash "index integer")) ; (if (not ...) (error:datum-out-of-range hash)) ; hash) ;1 ; ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> (runtime reader), read-top-level, restart ;-> (runtime reader), initial-db ;-> (runtime hash-table), %make-hash-table, (let), (let) ; evaluating ;(if (and initial-size (&> initial-size 4)) (begin (... table initial-size) (... table #t))) ; for ### in ;(begin |###| (reset-table! table) (if (... type) (record-address-hash-table! table)) table) ;-> (runtime state-space), %execute-at-new-state-point, (let), (let) ; evaluating ;(%translate-to-state-point old-root) ; for ### in ;(begin |###| value) ;1 ; ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> (runtime string-i/o-port), with-input-from-string ; evaluating ;(open-input-string string) ; for ### in ;(cons current-input-port |###|) ;-> (runtime string-i/o-port), open-input-string ; evaluating ;(let ((end ...)) (let (...) (make-textual-port string-input-type ...))) ;1 ; ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> (runtime reader), read-top-level, (let) ;-> (runtime reader), dispatch, (let), (let) ;-> (runtime reader), handler:symbol ;-> (runtime reader), read-atom, (let) ;-> (runtime list), for-each, map-1 ;-> (runtime string), %make-string-builder, (let), append-char! ; evaluating ;(fix:max max-cp (char-code char)) ; for ### in ;(set! max-cp |###|) ;-> (runtime primitive-arithmetic), loop ; evaluating ;(fx>? n m) ; for ### in ;(if |###| n m) ;1 ; ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> (runtime dynamic), parameterize* ; evaluating ;(fold-right (lambda (p bindings) (cons ... bindings)) bindings new-bindings) ; for ### in ;(let ((temp |###|)) (let (...) (shallow-fluid-bind swap! thunk swap!))) ;-> (runtime dynamic), (lambda) ; evaluating ;(create-binding (car p) (cdr p)) ; for ### in ;(cons |###| bindings) ;1 ; ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ; evaluating compiled code ;4 ; ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> (runtime reader), read-top-level, restart ;-> (runtime reader), initial-db ;-> (runtime hash-table), %make-hash-table, (let), (let) ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ; evaluating compiled code ;-> (runtime weak-pair), weak-list-set-add!, (let), loop ; evaluating ;(if (weak-pair? this) (let (... ...) (cond ... ... ...)) (begin (%record-set! set 2 ...) #t)) ;11 ; ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> (runtime reader), read-top-level, restart ;-> (runtime reader), initial-db ;-> (runtime hash-table), %make-hash-table, (let), (let) ;-> #[compiled-return-address 29 ("wind" #xc) #x11f #xcd0553] ;-> (runtime weak-pair), weak-list-set-add!, (let), loop, (let) ; evaluating ;(= item item*) ; for ### in ;(if |###| #f (loop next this)) ;-> (runtime equality), eqv? ; evaluating ;(or (eq? x y) (and (let ... ...) (let ... ...) (number:eqv? x y))) ;273 ; ;Unspecified return value 1 ]=>