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