From a3f3efe82dab413fdf79644645b0eee318f96033 Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Mon, 29 Mar 2010 11:24:06 +0200 Subject: [PATCH] Speed-up multiple calls to `org-diary'. Patch by Matt Lundin Matt writes: > The missing piece of the puzzle is integration with "diary" and > "cal-tex" functions via the org-diary sexp. I have found org-diary to be > excruciatingly slow when called for anything more than a couple of days. > I have the following line in my diary file: > > &%%(org-diary :timestamp :sexp) > > If I try to view 20 or so upcoming days in the diary by typing C-u 20 d > on a date in the calendar, it can take upwards of 30 seconds to generate > the diary display. This is of little consequence, since I can, after > all, simply use the custom agenda command. But I often want to print out > a nice LaTeX calendar of my appointments with cal-tex-cursor-month. And > that takes upwards of 50 seconds (see attached elp-results file). > > Judging from the elp-results, the culprit seems to be > org-prepare-agenda-buffers (46 seconds), which is called 31 times (once > for each day). It seems to me that since org-diary is being called 31 > times in quick succession by the same function (diary-sexp-entry), one > should only need to call org-prepare-agenda-buffers once. > > The only solution I could see to this problem was to add a test to see > if org-diary had been called less than 1 second ago. Thus, I added the > variable org-diary-last-run-time and a conditional in org-diary that > only runs org-prepare-agenda-buffers if org-diary-last-run-time is less > than 1 second in the past. > > With the patch, it now takes appr. 5 seconds to generate the LaTeX > calendar with cal-tex and org-prepare-agenda-buffers is called only > once. --- lisp/ChangeLog | 4 ++++ lisp/org-agenda.el | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 084e8f80c..23e242678 100755 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,9 @@ 2010-03-29 Carsten Dominik + * org-agenda.el (org-diary-last-run-time): New variable. + (org-diary): prepare agenda buffers only if last call was some + time ago. + * org-html.el (org-export-html-preprocess): Replace \ref macros with a link. (org-format-org-table-html): Add the label as an anchor. diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index adcefad80..61ddfd0de 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -4086,6 +4086,8 @@ Needed to avoid empty dates which mess up holiday display." (apply 'diary-add-to-list args) (apply 'add-to-diary-list args))) +(defvar org-diary-last-run-time nil) + ;;;###autoload (defun org-diary (&rest args) "Return diary information from org-files. @@ -4123,8 +4125,14 @@ function from a program - use `org-agenda-get-day-entries' instead." (let* ((files (if (and entry (stringp entry) (string-match "\\S-" entry)) (list entry) (org-agenda-files t))) + (time (org-float-time)) file rtn results) - (org-prepare-agenda-buffers files) + (when (or (not org-diary-last-run-time) + (> (- time + org-diary-last-run-time) + 3)) + (org-prepare-agenda-buffers files)) + (setq org-diary-last-run-time time) ;; If this is called during org-agenda, don't return any entries to ;; the calendar. Org Agenda will list these entries itself. (if org-disable-agenda-to-diary (setq files nil))