On Fri, May 1, 2020 at 10:02 PM Arthur A. Gleckler <[email protected]>
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 ]=>