Hi Mark, Thank you for your great writeup! Mark H Weaver writes: > * The (format #f ...) allocates a temporary string output port, and that … > with. Using 'number->string' there would reduce memory allocation of > the loop above by an order of magnitude or more. … > * The fact that you're using 'set!' to mutate 'longer' forces a > heap-allocated variable object to be allocated for 'longer', whereas > otherwise it could be allocated on the stack. See section 9.3.4 > (Variables and the VM) in the Guile 2.2 manual for more on this, and > how 'set!' often makes things much less efficient. > > * Since 'longer' is allocated within the loop, a new copy of that > (heap-allocated) variable object is created for each iteration. I implemented a version which avoids both points via let-recursion and number->string: (define (make-bgl lis cnt) "a bogus longer list" (let loop ((longer (cons (number->string cnt) lis)) (cnt cnt)) ;; periodically report statistics (when (eq? 0 (modulo cnt (* 1000 1000))) (begin (format #t "~A " cnt) (avg-gc-cpu-time))) (cond ;; periodically trim the list ((and (eq? 0 (modulo cnt (* 4123 1123)) (> (length longer) 0))) (loop (list) cnt)) ;; end recursion ((eq? 0 cnt) lis) (else (loop (cons (number->string cnt) longer) (- cnt 1)))))) This does indeed spend much less time in GC, but its memory usage is still rising rapidly. Did I unknowingly create a memory leak? Best wishes, Arne -- Unpolitisch sein heißt politisch sein ohne es zu merken