Weak hashtables affect GC performance more than I expected.
In my test (see below), GC time goes from 100ms to 20s, after creating a
reasonably large hashtable. Is it an expected performance degradation or a bug?
;; Create some data, so the GC has something to work on.
(defun make-tree (n)
(if (> n 0)
(let ((c (make-tree (- n 1))))
(list n c c))
(defparameter *data (make-tree 10000))
;; GC takes 0.07s
(time (gc :full t))
(defvar *ht* nil)
;; This function creates a weak hash table of size N, adds one element to it, runs and times GC.
(defun gc-time-with-weak-hashtable (n)
(setf *ht* nil)
(gc :full t)
(setf *ht* (make-hash-table :weakness :key :size n))
(let ((k (list n))
(setf (gethash k *ht*) nil)
(call-with-timing (lambda (&rest args)
(setf gc-time (getf args :gc-run-time-ms)))
(lambda () (gc :full t)))
(list n gc-time)))
;; Time GC for a range of hash table sizes. Time is in ms.
(loop for n from 0 to 7 collect (gc-time-with-weak-hashtable (* 1024 (expt 2 n))))
;; => ((1024 216) (2048 364) (4096 668) (8192 1272) (16384 2481) (32768 4908) (65536 9725) (131072 19421))