The myth of fingerprints, er, no, garbage collectors

"Tim Bradshaw (as tfb at tfeb dot org)" <[email protected]> Thu, 25 Jun 2026 17:17:24 +0100
Newsgroups gmane.lisp.lispworks.general
Message-ID <[email protected]>
Given this silly function:

(defun smash (n m)
  (declare (type fixnum n m))
  (let ((c nil))
    (dotimes (i n c)
      (setf c (cons 1 (if (zerop (mod i m)) nil c))))))

You can time it.  (smash (expt 10 9) 10)) allocates about 16GB, and takes 25 seconds.  GC time is about 0.3% of that time.

You can also watch GC time grow as it has to copy more: (smash (expt 10 9) 1000) makes lists which can grow to 1000 elts: GC now is well over 0.5% of the time.	Keeping lists of a million elements results in the GC taking 10% of the runtime.

The reason I have been playing with all these things is I keep finding myself writing functions which carefully allow you to, for instance pass in some object which they will then reuse instead of allocating one.  And after trying to measure if this was worthwhile, I realised that it almost never is: it's better to allocate the thing on the fly and throw it away, because the GC will then never see it at all, whereas if you hold onto it, it will.

As someone who remembers when a GC meant 'you can go and make a cup of tea now', modern GCs are wonderful things: we forget how spoiled we are.

--tim

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
[email protected]
http://www.lispworks.com/support/lisp-hug.html