Gnus development mailing list
 help / color / mirror / Atom feed
From: Dan Christensen <jdc@uwo.ca>
To: ding@gnus.org
Subject: Re: faster gnus-thread-latest-date
Date: Thu, 10 Dec 2009 22:01:07 -0500	[thread overview]
Message-ID: <87d42m2ozw.fsf@uwo.ca> (raw)
In-Reply-To: <87y6lbfs42.fsf@uwo.ca>

[-- Attachment #1: Type: text/plain, Size: 1076 bytes --]

Dan Christensen <jdc@uwo.ca> writes:

> I'm now thinking that caching the parsed time in "time value" format (a
> pair of integers) rather than a float might be more useful, since many
> parts of Gnus need this information.  

It turns out that someone thought of this before, and implemented it as
gnus-date-get-time in gnus-util, which caches the emacs time value as a
text property on the date string that is being parsed!  Clever idea:  it
works more generally than my method and doesn't require api changes to
various functions.  So all I had to do was call this function in a few
places, and things are faster.  For a group with about 6000 articles,
the time for sorting with gnus-thread-sort-by-most-recent-date when from
about 12 seconds to 1 second, and the time for generating the summary
went from 8 seconds to 6 seconds.

The patch below includes a ChangeLog.  It also adds a message to
gnus-sort-threads if the recursive sort fails and it falls back to the
loop.  That could be useful debugging information when timing these
things.

Please test and apply.

Dan


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: latest-date.patch --]
[-- Type: text/x-diff, Size: 4368 bytes --]

Index: ChangeLog
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/ChangeLog,v
retrieving revision 7.2042
diff -u -r7.2042 ChangeLog
--- ChangeLog	2 Dec 2009 12:10:00 -0000	7.2042
+++ ChangeLog	11 Dec 2009 02:53:52 -0000
@@ -1,3 +1,12 @@
+2009-12-10  Dan Christensen  <jdc@uwo.ca>
+
+	* gnus-util.el (gnus-user-date): Use gnus-date-get-time.
+	(gnus-dd-mmm): Use gnus-date-get-time.
+	* gnus-sum.el (gnus-thread-latest-date): Use gnus-date-get-time and
+	simplify logic.
+	(gnus-summary-limit-to-age): Use gnus-date-get-time.
+	(gnus-sort-threads): emit message if gnus-sort-threads-loop used.
+
 2009-12-02  Katsumi Yamaoka  <yamaoka@jpl.org>
 
 	* lpath.el: Always bind default-file-name-coding-system for (S)XEmacs.
Index: gnus-util.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/gnus-util.el,v
retrieving revision 7.89
diff -u -r7.89 gnus-util.el
--- gnus-util.el	9 Sep 2009 10:42:27 -0000	7.89
+++ gnus-util.el	11 Dec 2009 02:53:52 -0000
@@ -455,10 +455,10 @@
 
 (defun gnus-user-date (messy-date)
   "Format the messy-date according to gnus-user-date-format-alist.
-Returns \"  ?  \" if there's bad input or if an other error occurs.
+Returns \"  ?  \" if there's bad input or if another error occurs.
 Input should look like this: \"Sun, 14 Oct 2001 13:34:39 +0200\"."
   (condition-case ()
-      (let* ((messy-date (gnus-float-time (safe-date-to-time messy-date)))
+      (let* ((messy-date (gnus-float-time (gnus-date-get-time messy-date)))
 	     (now (gnus-float-time))
 	     ;;If we don't find something suitable we'll use this one
 	     (my-format "%b %d '%y"))
@@ -477,7 +477,7 @@
 (defun gnus-dd-mmm (messy-date)
   "Return a string like DD-MMM from a big messy string."
   (condition-case ()
-      (format-time-string "%d-%b" (safe-date-to-time messy-date))
+      (format-time-string "%d-%b" (gnus-date-get-time messy-date))
     (error "  -   ")))
 
 (defmacro gnus-date-get-time (date)
Index: gnus-sum.el
===================================================================
RCS file: /usr/local/cvsroot/gnus/lisp/gnus-sum.el,v
retrieving revision 7.245
diff -u -r7.245 gnus-sum.el
--- gnus-sum.el	30 Nov 2009 09:36:17 -0000	7.245
+++ gnus-sum.el	11 Dec 2009 02:53:58 -0000
@@ -4826,7 +4826,8 @@
 	  ;; Even after binding max-lisp-eval-depth, the recursive
 	  ;; sorter might fail for very long threads.  In that case,
 	  ;; try using a (less well-tested) non-recursive sorter.
-	  (error (gnus-sort-threads-loop
+	  (error (gnus-message 9 "Sorting threads with loop...")
+		 (gnus-sort-threads-loop
 		  threads (gnus-make-sort-function
 			   gnus-thread-sort-functions))))
       (gnus-message 8 "Sorting threads...done"))))
@@ -4993,22 +4994,17 @@
   "Sort threads such that the thread with the most recently dated article comes first."
   (> (gnus-thread-latest-date h1) (gnus-thread-latest-date h2)))
 
+; Since this is called not only to sort the top-level threads, but
+; also in recursive sorts to order the articles within a thread, each
+; article will be processed many times.  Thus it speeds things up
+; quite a bit to use gnus-date-get-time, which caches the time value.
 (defun gnus-thread-latest-date (thread)
   "Return the highest article date in THREAD."
-  (let ((previous-time 0))
-    (apply 'max
-	   (mapcar
-	    (lambda (header)
-	      (setq previous-time
-		    (condition-case ()
-			(gnus-float-time (mail-header-parse-date
-					  (mail-header-date header)))
-		      (error previous-time))))
-	    (sort
-	     (message-flatten-list thread)
-	     (lambda (h1 h2)
-	       (< (mail-header-number h1)
-		  (mail-header-number h2))))))))
+  (apply 'max
+	 (mapcar '(lambda (header) (gnus-float-time 
+				    (gnus-date-get-time
+				     (mail-header-date header))))
+		 (message-flatten-list thread))))
 
 (defun gnus-thread-total-score-1 (root)
   ;; This function find the total score of the thread below ROOT.
@@ -8232,9 +8228,7 @@
 	  (when (and (vectorp (gnus-data-header d))
 		     (setq date (mail-header-date (gnus-data-header d))))
 	    (setq is-younger (time-less-p
-			      (time-since (condition-case ()
-					      (date-to-time date)
-					    (error '(0 0))))
+			      (time-since (gnus-date-get-time date))
 			      cutoff))
 	    (when (if younger-p
 		      is-younger

  reply	other threads:[~2009-12-11  3:01 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-07 21:27 Dan Christensen
2009-12-08  3:35 ` Dan Christensen
2009-12-08  7:07   ` Katsumi Yamaoka
2009-12-08 19:14   ` Ted Zlatanov
2009-12-09  0:33     ` Dan Christensen
2009-12-10  3:03       ` Dan Christensen
2009-12-11  3:01         ` Dan Christensen [this message]
2009-12-11 22:03           ` Dan Christensen
2009-12-13 23:25             ` Dan Christensen
2009-12-14 16:18               ` Dave Love
2009-12-13 23:56           ` Dan Christensen
2010-01-02  2:09             ` Dan Christensen
2010-01-12 17:17               ` Reiner Steib
2010-06-09 13:42             ` Dan Christensen
2010-06-10  0:32               ` Katsumi Yamaoka
2010-06-10  8:42                 ` Gnus new commits (was: faster gnus-thread-latest-date) Ted Zlatanov
2009-12-13 10:29   ` faster gnus-thread-latest-date Daniel Pittman
2009-12-13 23:38     ` Dan Christensen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87d42m2ozw.fsf@uwo.ca \
    --to=jdc@uwo.ca \
    --cc=ding@gnus.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).