From 8ad4e1cf3166b32339fb345cc620a6347033a37f Mon Sep 17 00:00:00 2001 From: Yogthos Date: Fri, 26 Jun 2026 00:42:40 -0400 Subject: [PATCH] Intern no-ns keywords without per-call allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (keyword #f name) built a fresh combined-key string (string-append) on every call just to do the intern-table lookup — ~80 bytes of garbage per (:kw x), map literal, keyword arg, etc. A no-ns keyword now interns in a table keyed by the name string directly, so a lookup of an already-interned keyword is one hashtable-ref with no allocation. The ns table keeps the combined key; both share the keyword-t khash (equal-hash of the combined key) so hash values are unchanged. Small time win on its own (the field-read dispatch dominates hot record code — see jolt-unx4) but removes per-call keyword allocation everywhere. Runtime .ss, no re-mint; identity/=/hash unchanged, make test green. --- host/chez/values.ss | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/host/chez/values.ss b/host/chez/values.ss index b0ebed5..00e01d2 100644 --- a/host/chez/values.ss +++ b/host/chez/values.ss @@ -23,15 +23,26 @@ ;; --- keywords: interned so identity works; optional namespace ---------------- (define-record-type keyword-t (fields ns name khash) (nongenerative keyword-v1)) (define keyword-table (make-hashtable string-hash string=?)) +;; The common no-ns keyword is interned in a table keyed by NAME directly, so a +;; lookup of an already-interned :kw (the hot case — every (:kw x), map literal, +;; keyword arg) is one hashtable-ref with NO allocation. The ns table keeps the +;; combined key. Both share the keyword-t khash (equal-hash of the combined key), +;; so hash values are unchanged. +(define keyword-table-bare (make-hashtable string-hash string=?)) ;; NUL separator can't occur in a keyword ns/name, so the intern key is ;; unambiguous (a "/" separator would collide ns="a" name="b/c" with ns="a/b"). (define (keyword-intern-key ns name) (string-append (or ns "") "\x0;" name)) (define (keyword ns name) - (let ((k (keyword-intern-key ns name))) - (or (hashtable-ref keyword-table k #f) - (let ((kw (make-keyword-t ns name (equal-hash k)))) - (hashtable-set! keyword-table k kw) - kw)))) + (if ns + (let ((k (keyword-intern-key ns name))) + (or (hashtable-ref keyword-table k #f) + (let ((kw (make-keyword-t ns name (equal-hash k)))) + (hashtable-set! keyword-table k kw) + kw))) + (or (hashtable-ref keyword-table-bare name #f) + (let ((kw (make-keyword-t #f name (equal-hash (keyword-intern-key #f name))))) + (hashtable-set! keyword-table-bare name kw) + kw)))) (define (keyword? x) (keyword-t? x)) ;; --- symbols: ns + name + meta; NOT interned (meta varies), = by ns/name ------