Fast record field reads: single eq? scan, skip the get-arm walk
(:field rec) / (get rec :field) lowers to (jolt-get rec kw), which walked the get-arm list to reach the jrec arm, then did jrec-has? + jrec-lookup — TWO linear scans, each comparing keys through the generic jolt=2 equality dispatcher. Field keys are interned keywords, so: - jrec-key=? compares a keyword query by eq? (jolt=2 only for non-keyword keys), - jrec-ref does ONE scan (vs has?+lookup) and runs a deftype's ILookup valAt only when the field is genuinely absent (present-nil still returns nil, not default), - jolt-get-dispatch checks jrec? first, skipping the get-arm walk for the hottest get target. jrec-lookup/jrec-has? (used by =, contains?, etc.) get the fast compare too. binary-trees 135x->18.9x, dispatch 121x->26.4x, mono-dispatch 327x->108x vs JVM. Runtime .ss (collections.ss + records.ss), no re-mint; make test + shakesmoke + buildsmoke green, record get/assoc/keys/=/count semantics unchanged.
This commit is contained in:
parent
8ad4e1cf31
commit
707737d989
2 changed files with 32 additions and 13 deletions
|
|
@ -239,11 +239,16 @@
|
|||
((string? coll) (let ((i (->idx k)))
|
||||
(if (and (fixnum? i) (fx>=? i 0) (fx<? i (string-length coll))) (string-ref coll i) d)))
|
||||
(else d)))
|
||||
;; jrec? / jrec-ref live in records.ss (loaded later); these are forward references
|
||||
;; resolved at call time. A record field read is the hottest get, so check it first
|
||||
;; and skip the get-arm walk.
|
||||
(define (jolt-get-dispatch coll k d)
|
||||
(let loop ((as jolt-get-arms))
|
||||
(cond ((null? as) (jolt-get-base coll k d))
|
||||
(((caar as) coll) ((cdar as) coll k d))
|
||||
(else (loop (cdr as))))))
|
||||
(if (jrec? coll)
|
||||
(jrec-ref coll k d)
|
||||
(let loop ((as jolt-get-arms))
|
||||
(cond ((null? as) (jolt-get-base coll k d))
|
||||
(((caar as) coll) ((cdar as) coll k d))
|
||||
(else (loop (cdr as)))))))
|
||||
(define jolt-get
|
||||
(case-lambda
|
||||
((coll k) (jolt-get-dispatch coll k jolt-nil))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue