Andrew,

Sorry for taking a long time getting back.  I finally went deeper into the net 
worth barchart report (which is also used to create the income/expenses chart 
report), and found that changing the report-utilities.scm's 
gnc:get-comm-balance-at-date function to NOT use qof resulted in a tremendous 
increase in speed.  Now, I'm not sure that is an acceptable solution -- 
particularly when we are trying to transition to be closer to SQL.  
Nevertheless, I've attached the patch (report-utilities.patch) for this part.

However, for cash flow report, I got that to run in less than a second too 
(processing all of my transactions dating back to 2006 -- something like 5000 
transactions).  The problem there was that the line:
                          (gnc:report-percent-done (* 85 (/ work-done 
splits-to-do))))

Was being run thousands of times.  That is a quite expensive call just to 
update the progress -- particularly if you have thousands of splits to do.  
What I did was change it to only update the progress every time it changes by 
1%.  The progress still seems to move quite smoothly (in the short time that 
it runs -- it runs really fast.

So...there are two patches attached.

Let me know if it works, and I'm curious what others have to say about the 
idea of swapping that report-utilities method to not use qof.  It is also 
possible that I'm missing something since for different commodities, maybe 
the qof method is more accurate.  I doubt that is the case, though.

By the way, I've subscribed to the gnucash-devel digest.

-Tim

Index: src/report/standard-reports/cash-flow.scm
===================================================================
--- src/report/standard-reports/cash-flow.scm	(revision 17795)
+++ src/report/standard-reports/cash-flow.scm	(working copy)
@@ -152,23 +152,28 @@
     (define (same-account? a1 a2)
       (string=? (gncAccountGetGUID a1) (gncAccountGetGUID a2)))
 
-    (define (same-split? s1 s2) 
-      (string=? (gncSplitGetGUID s1) (gncSplitGetGUID s2)))
+    (define accounts-hashed
+     (let ((accounts-hashed (make-hash-table 100)))
+      (for-each
+       (lambda (account)
+        (hash-set! accounts-hashed (gncAccountGetGUID account) #t))
+       accounts)
+      accounts-hashed))
 
-    (define account-in-list?
-      (lambda (account accounts)
-        (cond
-          ((null? accounts) #f)
-          ((same-account? (car accounts) account) #t)
-          (else (account-in-list? account (cdr accounts))))))
+    (define seen-splits-map (make-hash-table 100))
+    
+    (define account-in-accounts-list?
+     (lambda (account)
+      (hash-ref accounts-hashed (gncAccountGetGUID account))))
 
-    (define split-in-list? 
-      (lambda (split splits)
-	(cond 
-	 ((null? splits) #f)
-	 ((same-split? (car splits) split) #t)
-	 (else (split-in-list? split (cdr splits))))))
+    (define split-seen?
+     (lambda (split)
+      (hash-ref seen-splits-map (gncSplitGetGUID split))))
 
+    (define add-split-seen
+     (lambda (split)
+      (hash-set! seen-splits-map (gncSplitGetGUID split) #t)))
+
     (define account-in-alist
       (lambda (account alist)
         (cond
@@ -204,7 +209,7 @@
         (let ((sub-accounts (gnc:acccounts-get-all-subaccounts accounts)))
           (for-each
             (lambda (sub-account)
-              (if (not (account-in-list? sub-account accounts))
+              (if (not (account-in-accounts-list? sub-account))
                   (set! accounts (append accounts sub-accounts))))
             sub-accounts)))
 
@@ -226,6 +231,10 @@
 
                (money-diff-collector (gnc:make-commodity-collector))
 	       (splits-to-do (gnc:accounts-count-splits accounts))
+	       ; Only update the progress by increasing it by 1% every time that sufficient
+	       ; number of splits are done to warrant incrementing it.
+	       (progress-update-interval 
+		    (if (> splits-to-do 85) (quotient splits-to-do 85) 1))
 	       (seen-split-list '())
 	       (time-exchange-fn #f)
 	       (commodity-list #f))
@@ -252,7 +261,8 @@
                   (for-each
                     (lambda (split)
 		      (set! work-done (+ 1 work-done))
-		      (gnc:report-percent-done (* 85 (/ work-done splits-to-do)))
+		      (if (equal? 0 (modulo work-done progress-update-interval))
+			  (gnc:report-percent-done (* 85 (/ work-done splits-to-do))))
                       (let ((parent (xaccSplitGetParent split)))
                         (if (and (gnc:timepair-le (gnc-transaction-get-date-posted parent) to-date-tp)
                                  (gnc:timepair-ge (gnc-transaction-get-date-posted parent) from-date-tp))
@@ -278,10 +288,10 @@
                                   ;(gnc:debug (xaccAccountGetName s-account))
                                   (if (and	 ;; make sure we don't have
 				       (not (null? s-account)) ;;  any dangling splits
-				       (not (account-in-list? s-account accounts)))
-				      (if (not (split-in-list? s seen-split-list))
+				       (not (account-in-accounts-list? s-account)))
+				      (if (not (split-seen? s))
 					  (begin  
-					    (set! seen-split-list (cons s seen-split-list))
+					    (add-split-seen s) 
 					    (if (gnc-numeric-negative-p s-value)
 						(let ((pair (account-in-alist s-account money-in-alist)))
 						  ;(gnc:debug "in:" (gnc-commodity-get-printname s-commodity)
@@ -304,6 +314,7 @@
 						    (money-in-collector 'add report-currency s-report-value)
 						    (s-account-in-collector 'add report-currency s-report-value))
 						  )
+						; Else s-value positive
 						(let ((pair (account-in-alist s-account money-out-alist)))
 						  ;(gnc:debug "out:" (gnc-commodity-get-printname s-commodity)
 						;	     (gnc-numeric-to-double s-amount)
Index: src/report/report-system/report-utilities.scm
===================================================================
--- src/report/report-system/report-utilities.scm	(revision 17795)
+++ src/report/report-system/report-utilities.scm	(working copy)
@@ -275,12 +275,22 @@
                    (gnc:warn 
                     "gnc:numeric-collector called with wrong argument: "
                     amount)))
+	((minus) (if (gnc:gnc-numeric? amount) 
+                   (set! value (gnc-numeric-add (gnc-numeric-neg amount) value
+                                                GNC-DENOM-AUTO GNC-DENOM-LCD))
+                   (gnc:warn 
+                    "gnc:numeric-collector called with wrong argument: "
+                    amount)))
 	((total) value)
 	(else (gnc:warn "bad gnc:numeric-collector action: " action))))))
 
 ;; Replace all 'action function calls by the normal functions below.
 (define (gnc:numeric-collector-add collector amount)
   (collector 'add amount))
+
+(define (gnc:numeric-collector-minus collector amount)
+  (collector 'minus amount))
+
 (define (gnc:numeric-collector-total collector)
   (collector 'total #f))
 
@@ -458,9 +468,7 @@
 ;; values rather than double values.
 (define (gnc:account-get-comm-balance-at-date account 
 					      date include-children?)
-  (let ((balance-collector (gnc:make-commodity-collector))
-	(query (qof-query-create-for-splits))
-	(splits #f))
+  (let ((balance-collector (gnc:make-commodity-collector)))
 
       (if include-children?
 	  (for-each 
@@ -470,24 +478,9 @@
 	    (lambda (child)
 	      (gnc:account-get-comm-balance-at-date child date #f))
 	    account)))
-
-      (qof-query-set-book query (gnc-get-current-book))
-      (xaccQueryAddSingleAccountMatch query account QOF-QUERY-AND)
-      (xaccQueryAddDateMatchTS query #f date #t date QOF-QUERY-AND)
-      (qof-query-set-sort-order query
-				(list SPLIT-TRANS TRANS-DATE-POSTED)
-				(list QUERY-DEFAULT-SORT)
-				'())
-      (qof-query-set-sort-increasing query #t #t #t)
-      (qof-query-set-max-results query 1)
-      
-      (set! splits (qof-query-run query))
-      (qof-query-destroy query)
-
-      (if (and splits (not (null? splits)))
-	  (gnc-commodity-collector-add balance-collector
+      (gnc-commodity-collector-add balance-collector
 				       (xaccAccountGetCommodity account)
-				       (xaccSplitGetBalance (car splits))))
+				       (xaccAccountGetBalanceAsOfDate account (gnc:timepair->secs date)))
       balance-collector))
 
 ;; Calculate the increase in the balance of the account in terms of
_______________________________________________
gnucash-devel mailing list
gnucash-devel@gnucash.org
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

Reply via email to