gnucash stable: [report-utilities.scm] optimise some loops

Christopher Lam clam at code.gnucash.org
Wed May 7 20:43:11 EDT 2025


Updated	 via  https://github.com/Gnucash/gnucash/commit/8bd2d10c (commit)
	from  https://github.com/Gnucash/gnucash/commit/f71ddb73 (commit)



commit 8bd2d10cff74285583939ec899d42dd5ece5ad98
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Wed May 7 23:25:58 2025 +0800

    [report-utilities.scm] optimise some loops
    
    reduced from O(2*N) for list-ref-safe and O(4*N) for list-set-safe! to
    O(N).

diff --git a/gnucash/report/report-utilities.scm b/gnucash/report/report-utilities.scm
index e89c54e1e7..a1b90ff5e5 100644
--- a/gnucash/report/report-utilities.scm
+++ b/gnucash/report/report-utilities.scm
@@ -106,20 +106,24 @@
 (export gnc:dump-lot)
 
 (define (list-ref-safe list elt)
-  (and (> (length list) elt)
-       (list-ref list elt)))
+  (and (pair? list)
+       (if (<= elt 0)
+           (car list)
+           (list-ref-safe (cdr list) (1- elt)))))
 
 (define (list-set-safe! l elt val)
-  (unless (list? l)
-    (set! l '()))
-  (if (> (length l) elt)
-      (list-set! l elt val)
-      (let loop ((filler (list val))
-                 (i (length l)))
-        (if (< i elt)
-            (loop (cons #f filler) (1+ i))
-            (set! l (append! l filler)))))
-  l)
+  (define (extend-tail i)
+    (if (>= i elt)
+        (list val)
+        (cons #f (extend-tail (1+ i)))))
+  (if (null? l)
+      (extend-tail 0)
+      (let loop ((i 0) (curr l))
+        (cond
+         ((not (pair? curr)) (error "list-set-safe: improper list"))
+         ((>= i elt)         (set-car! curr val) l)
+         ((null? (cdr curr)) (set-cdr! curr (extend-tail (1+ i))) l)
+         (else               (loop (1+ i) (cdr curr)))))))
 
 ;; Just for convenience. But in reports you should rather stick to the
 ;; style-info mechanism and simple plug the <gnc-monetary> into the



Summary of changes:
 gnucash/report/report-utilities.scm | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)



More information about the gnucash-changes mailing list