From e5b756fada5464a6c81ca1445523f4b5e6f8739d Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Sun, 21 Jul 2019 20:35:28 +0800 Subject: [PATCH] [commodity-utils] refactor gnc:pricelist-price-find-nearest instead of O(3n), this implementation is O(n) --- .../report-system/commodity-utilities.scm | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/gnucash/report/report-system/commodity-utilities.scm b/gnucash/report/report-system/commodity-utilities.scm index 592da36488..8360a67933 100644 --- a/gnucash/report/report-system/commodity-utilities.scm +++ b/gnucash/report/report-system/commodity-utilities.scm @@ -295,27 +295,21 @@ construct with gnc:make-gnc-monetary and gnc:monetary->string instead.") ;; pricelist comes from ;; e.g. gnc:get-commodity-totalavg-prices. Returns a or, ;; if pricelist was empty, #f. -(define (gnc:pricelist-price-find-nearest - pricelist date) - (let* ((later (find (lambda (p) - (< date (car p))) - pricelist)) - (earlierlist (take-while - (lambda (p) - (>= date (car p))) - pricelist)) - (earlier (and (not (null? earlierlist)) - (last earlierlist)))) - - (if (and earlier later) - (if (< (abs (- date (car earlier))) - (abs (- date (car later)))) - (cadr earlier) - (cadr later)) - (or - (and earlier (cadr earlier)) - (and later (cadr later)))))) - +(define (gnc:pricelist-price-find-nearest pricelist date) + (let lp ((pricelist pricelist)) + (cond + ((null? pricelist) #f) + ((null? (cdr pricelist)) (cadr (car pricelist))) + (else + (let ((earlier (car pricelist)) + (later (cadr pricelist))) + (cond + ((< (car later) date) + (lp (cdr pricelist))) + ((< (- date (car earlier)) (- (car later) date)) + (cadr earlier)) + (else + (cadr later)))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Functions to get one price at a given time (i.e. not time-variant).