Re: master: Reduce empty hash-table struct size for default rehash params
Stas Boukarev <[email protected]> Sun, 1 Mar 2026 18:58:04 +0300
| Newsgroups | gmane.lisp.steel-bank.cvs,gmane.lisp.steel-bank.devel |
|---|---|
| Message-ID | <CAF63=12LNqY50iGCtp7F1jD2fS8sBOb7njHBmrPE7tfDsD4pBg@mail.gmail.com> |
(equalp (make-hash-table :rehash-threshold 0.3) (make-hash-table :rehash-threshold 0.9)) => NIL On Sun, Mar 1, 2026 at 6:06 PM snuglas via Sbcl-commits <[email protected]> wrote: > > The branch "master" has been updated in SBCL: > via 54ea7a25b4e9a53c864cb80f445c526c2662c0e8 (commit) > from 083bf9756dcd9093906a6d2654027315660299f9 (commit) > > - Log ----------------------------------------------------------------- > commit 54ea7a25b4e9a53c864cb80f445c526c2662c0e8 > Author: Douglas Katzman <[email protected]> > Date: Sun Mar 1 08:44:01 2026 -0500 > > Reduce empty hash-table struct size for default rehash params > > Now 128 bytes (down from 160 bytes) if #+compact-instance-header > --- > src/code/hash-table.lisp | 54 +++++++++++++++++++-------------------- > src/code/target-hash-table.lisp | 26 ++++++++++++++----- > src/compiler/generic/genesis.lisp | 1 - > 3 files changed, 45 insertions(+), 36 deletions(-) > > diff --git a/src/code/hash-table.lisp b/src/code/hash-table.lisp > index 12b8a0d28..d2862e2c6 100644 > --- a/src/code/hash-table.lisp > +++ b/src/code/hash-table.lisp > @@ -67,11 +67,8 @@ > puthash-impl > remhash-impl > %hash-fun-state > - test > test-fun > hash-fun > - rehash-size > - rehash-threshold > pairs > index-vector > next-vector > @@ -146,28 +143,6 @@ > ;; next GC. It may take HASH-FUN-STATE as an extra argument. > (hash-fun nil :type function) > > - ;; The type of hash table this is. Part of the exported interface, > - ;; as well as needed for the MAKE-LOAD-FORM and PRINT-OBJECT methods. > - (test nil :type (or symbol function) :read-only t) > - ;; How much to grow the hash table by when it fills up. If an index, > - ;; then add that amount. If a floating point number, then multiply > - ;; it by that. > - (rehash-size nil :type #+c-headers-only real > - #-c-headers-only (or index (single-float (1.0))) > - :read-only t) > - ;; How full the hash table has to get before we rehash > - ;; but only for the initial determination of how many buckets to make. > - ;; Subsequent resizing is at our discretion. i.e. you might think that a > - ;; deliberate choice of rehash size and threshold implies that you want the new > - ;; table to be X amount larger *and* that you care at about what load factor the > - ;; new table gets rehashed, but no, you don't get to pick both every time. > - ;; (CLHS says that these are all just "hints" and we're free to ignore) > - ;; If #+c-headers-only, the type is weakened to one which generates the right > - ;; C type without parsing a float. (NUMBER or T would result in the type being > - ;; lispobj, while WORD would give the struct field an incorrect name) > - (rehash-threshold nil :type #+c-headers-only single-float > - #-c-headers-only (single-float (0.0) 1.0) > - :read-only t) > ;; The current number of entries in the table. > (%count 0 :type index) > ;; Index into the Next vector chaining together free slots in the KV > @@ -197,15 +172,38 @@ > puthash-impl > remhash-impl > %hash-fun-state > - test > + %test > test-fun > hash-fun > - rehash-size > - rehash-threshold > + %rehash-size > + %rehash-threshold > pairs > index-vector > next-vector > hash-vector))) > + ;; The type of hash table this is. Part of the exported interface, > + ;; as well as needed for the MAKE-LOAD-FORM and PRINT-OBJECT methods. > + ;; Inferrable from FLAGS except unless a custom function. > + (%test nil :type (or symbol function) :read-only t) > + ;; How much to grow the hash table by when it fills up. If an index, > + ;; then add that amount. If a floating point number, then multiply > + ;; it by that. > + (%rehash-size nil :type #+c-headers-only real > + #-c-headers-only (or index (single-float (1.0))) > + :read-only t) > + ;; How full the hash table has to get before we rehash > + ;; but only for the initial determination of how many buckets to make. > + ;; Subsequent resizing is at our discretion. i.e. you might think that a > + ;; deliberate choice of rehash size and threshold implies that you want the new > + ;; table to be X amount larger *and* that you care at about what load factor the > + ;; new table gets rehashed, but no, you don't get to pick both every time. > + ;; (CLHS says that these are all just "hints" and we're free to ignore) > + ;; If #+c-headers-only, the type is weakened to one which generates the right > + ;; C type without parsing a float. (NUMBER or T would result in the type being > + ;; lispobj, while WORD would give the struct field an incorrect name) > + (%rehash-threshold nil :type #+c-headers-only single-float > + #-c-headers-only (single-float (0.0) 1.0) > + :read-only t) > ;; List of (pair-index . bucket-number) which GC smashed and are almost > ;; equivalent to free cells, except that they are not yet unlinked from > ;; their chain. Skipping the removal in GC eliminates a race with REMHASH. > diff --git a/src/code/target-hash-table.lisp b/src/code/target-hash-table.lisp > index 7df2a7a6f..cb91b5a06 100644 > --- a/src/code/target-hash-table.lisp > +++ b/src/code/target-hash-table.lisp > @@ -13,8 +13,7 @@ > (in-package "SB-IMPL") > > > -(defvar *show-putweak* nil) > - > +(declaim (freeze-type general-hash-table)) > (!begin-collecting-cold-init-forms) > > (declaim (ftype (sfunction (hash-table t maybe-truncated-hash) > @@ -1092,11 +1091,13 @@ Examples: > (pick-table-methods (logtest flags hash-table-synchronized-flag) > (if userfunp nil test) hash-fun-state))) > (table > - (funcall (if weakp #'%alloc-general-hash-table #'%alloc-hash-table) > - flags getter setter remover hash-fun-state > - test test-fun hash-fun > - rehash-size rehash-threshold > - kv-vector index-vector next-vector hash-vector))) > + (if (or (/= rehash-threshold 1) (/= rehash-size default-rehash-size) userfunp weakp) > + (%alloc-general-hash-table flags getter setter remover hash-fun-state > + test test-fun hash-fun > + rehash-size rehash-threshold > + kv-vector index-vector next-vector hash-vector) > + (%alloc-hash-table flags getter setter remover hash-fun-state test-fun hash-fun > + kv-vector index-vector next-vector hash-vector)))) > (declare (type index scaled-size)) > ;; The trailing metadata element is either the table itself or the hash-vector > ;; depending on weakness. Non-weak hashing vectors can be GCed without looking > @@ -3287,6 +3288,17 @@ table itself." > ;;; so its effect would just get clobbered by the defstruct. > (sb-kernel::assign-equalp-impl 'hash-table #'hash-table-equalp) > > +(defun hash-table-test (hash-table) > + (if (typep hash-table 'general-hash-table) > + (hash-table-%test hash-table) > + (aref #(eq eql equal equalp) (ht-flags-kind (hash-table-flags hash-table))))) > +(defun hash-table-rehash-threshold (hash-table) > + (if (typep hash-table 'general-hash-table) (hash-table-%rehash-threshold hash-table) 1.0f0)) > +(defun hash-table-rehash-size (hash-table) > + (if (typep hash-table 'general-hash-table) > + (hash-table-%rehash-size hash-table) > + default-rehash-size)) > + > (!defun-from-collected-cold-init-forms !hash-table-cold-init) > > #| > diff --git a/src/compiler/generic/genesis.lisp b/src/compiler/generic/genesis.lisp > index 5a321706f..10fd99601 100644 > --- a/src/compiler/generic/genesis.lisp > +++ b/src/compiler/generic/genesis.lisp > @@ -4571,7 +4571,6 @@ static inline uword_t word_has_stickymark(uword_t word) { > (format stream "~&#include \"~A.h\"~%" > (string-downcase (sb-vm:primitive-object-name obj))))))) > ;; For purposes of the C code, cast all hash tables as general_hash_table > - ;; even if they lack the slots for weak tables. > (out-to "hash-table" > (write-structure-type (layout-info (find-layout 'sb-impl::general-hash-table)) > stream "hash_table")) > > ----------------------------------------------------------------------- > > > hooks/post-receive > -- > SBCL > > > _______________________________________________ > Sbcl-commits mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/sbcl-commits _______________________________________________ Sbcl-commits mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/sbcl-commits