home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / gnu / emacs / gnus / 1418 < prev    next >
Encoding:
Text File  |  1992-12-21  |  5.9 KB  |  186 lines

  1. Xref: sparky gnu.emacs.gnus:1418 gnu.emacs.sources:894
  2. Newsgroups: gnu.emacs.gnus,gnu.emacs.sources
  3. Path: sparky!uunet!cs.utexas.edu!uwm.edu!ux1.cso.uiuc.edu!news.cso.uiuc.edu!128.174.5.61!marca
  4. From: marca@ncsa.uiuc.edu (Marc Andreessen)
  5. Subject: Re: GNUS need not be slow (Source announcement)
  6. References: <BzH31D.6EA@ssr.com>
  7. X-Md4-Signature: 358a885fa9be05b41a7776b135b85310
  8. Message-ID: <MARCA.92Dec19064725@wintermute.ncsa.uiuc.edu>
  9. Sender: usenet@news.cso.uiuc.edu (Net Noise owner)
  10. Organization: Nat'l Center for Supercomputing Applications
  11. In-Reply-To: sdb@ssr.com's message of Fri, 18 Dec 1992 20:46:24 GMT
  12. Date: Sat, 19 Dec 1992 11:47:25 GMT
  13. Lines: 171
  14.  
  15. People not yet familiar with the gnus-speedup code previously posted
  16. more than once may want to try it first.  I have no idea how it
  17. compares with Scott's new code, but it does speed up stock GNUS quite
  18. a bit and is trivial to install.  Here 'tis:
  19.  
  20. ;; gnus-speedups|Felix Lee|flee@cs.psu.edu
  21. ;; |Simple performance enhancements for GNUS
  22. ;; |1992-05-18|1.2: stable||
  23.  
  24. ;; This package contains two plug-compatible performance enhancements
  25. ;; for GNUS 3.13 and 3.14:
  26.  
  27. ;; 1. A faster version of gnus-find-new-newsgroups, for making GNUS
  28. ;; start more quickly.
  29.  
  30. ;; 2. Faster subject and date sorting in the *Subject* buffer.
  31.  
  32. ;; This file must be loaded after "gnus.el".  You can do this by
  33. ;; adding '(load "gnus-speedups") at the end of your local gnus
  34. ;; wrapper, or at the end of "gnus.el".  Or you could just include
  35. ;; this file directly.
  36.  
  37. (require 'gnus)
  38.  
  39. ;;;;;
  40. ;; 1. A faster version of gnus-find-new-newsgroups.
  41.  
  42. ;; We reduce an O(N**2) process to O(N) by building a hash table for
  43. ;; the list of known newsgroups.  (It's a little strange that GNUS
  44. ;; doesn't already have a hash table for this.)
  45.  
  46. (defun gnus-find-new-newsgroups ()
  47.   "Look for new newsgroups and return names.
  48. `-n' option of options line in .newsrc file is recognized."
  49.   (let ( (group nil)
  50.      (new-groups nil)
  51.      (known-groups (gnus-make-hashtable)) )
  52.     ;; Build a table of known newsgroups.
  53.     (mapcar
  54.      (function (lambda (group) (gnus-sethash (car group) t known-groups)))
  55.      gnus-killed-assoc)
  56.     (mapcar
  57.      (function (lambda (group) (gnus-sethash (car group) t known-groups)))
  58.      gnus-newsrc-assoc)
  59.     ;; Compare the active file against what's known.
  60.     (mapatoms
  61.      (function
  62.       (lambda (sym)
  63.     (setq group (symbol-name sym))
  64.     ;; Take into account the -n option.
  65.     (and (or (null gnus-newsrc-options-n-no)
  66.          (not (string-match gnus-newsrc-options-n-no group))
  67.          (and gnus-newsrc-options-n-yes
  68.               (string-match gnus-newsrc-options-n-yes group)))
  69.          (null (gnus-gethash group known-groups))
  70.          (setq new-groups (cons group new-groups)))
  71.     ))
  72.      gnus-active-hashtb)
  73.     new-groups
  74.     ))
  75.  
  76.  
  77. ;;;;;
  78. ;; 2. Faster subject and date sorting in the *Subject* buffer.
  79.  
  80. ;; The basic idea is explained in 'gnus-keyed-sort.
  81.  
  82. ;; Sample hook usage:
  83. ;; (setq gnus-Select-group-hook
  84. ;;     (function
  85. ;;      (lambda ()
  86. ;;        (gnus-keyed-sort-headers
  87. ;;         (function gnus-string-lessp)
  88. ;;         (function (lambda (it) (gnus-simplify-subject it 're-only))))
  89. ;;        )))
  90.  
  91. (defun gnus-keyed-sort (list compare extract)
  92.   "Sort LIST stably and return the sorted list.  Does not modify LIST.
  93. Arguments are (LIST COMPARE EXTRACT).  Elements in the list are
  94. compared as if the predicate were:
  95.     (COMPARE (EXTRACT a) (EXTRACT b))
  96. but EXTRACT is run over each element of the list in a preprocessing
  97. stage for efficiency.  This reduces the number of EXTRACT calls from
  98. O(N log N) to O(N).
  99.  
  100. Example: (gnus-keyed-sort load-path 'string< 'downcase)
  101. "
  102.   (let ( (keyed-list
  103.       (mapcar
  104.        (function (lambda (it) (cons (funcall extract it) it)))
  105.        list)) )
  106.     (setq keyed-list
  107.       (sort keyed-list
  108.         (function
  109.          (lambda (a b) (funcall compare (car a) (car b))))))
  110.     (mapcar (function (lambda (it) (cdr it)))
  111.         keyed-list)
  112.     ))
  113.  
  114. (defun gnus-keyed-sort-headers (compare extract)
  115.   "Sort current group's headers by COMPARE and EXTRACT.  Sorting is
  116. done as if the predicate were
  117.     (COMPARE (EXTRACT a) (EXTRACT b))
  118. See 'gnus-keyed-sort for details.
  119. Note: interrupting the sort leaves the headers unsorted.
  120. "
  121.   (setq gnus-newsgroup-headers
  122.     (gnus-keyed-sort
  123.      gnus-newsgroup-headers
  124.      compare extract)))
  125.  
  126. (defun gnus-Subject-keyed-sort-subjects (compare extract &optional reverse)
  127.   "Sort and redisplay the *Subject* buffer by COMPARE and EXTRACT.
  128. Calls 'gnus-keyed-sort-headers to do the sorting.  Optional argument
  129. REVERSE means to do an 'nreverse after sorting.
  130. "
  131.   (let ( (current (gnus-Subject-article-number)) )
  132.     (gnus-keyed-sort-headers compare extract)
  133.     (if reverse
  134.     (setq gnus-newsgroup-headers (nreverse gnus-newsgroup-headers)))
  135.     (gnus-Subject-prepare)
  136.     (gnus-Subject-goto-subject current)
  137.     ))
  138.  
  139. ;; XXX It should be 'gnus-sort-fold-case, not 'case-fold-search
  140. (defun gnus-Subject-sort-by-subject (reverse)
  141.   "Sort *Subject* buffer by subject alphabetically.  Argument REVERSE
  142. means reverse order.  \"Re:\"s are ignored.  If 'case-fold-search, then
  143. case of letters will be ignored.
  144. "
  145.   (interactive "P")
  146.   ;; The main complication here is we try to speed up the sort process
  147.   ;; by hoisting conditions outside the sort.
  148.   (gnus-Subject-keyed-sort-subjects
  149.    'string<
  150.    (if case-fold-search
  151.        (function
  152.     (lambda (it)
  153.       (downcase (gnus-simplify-subject (nntp-header-subject it) 're-only))))
  154.      (function
  155.       (lambda (it)
  156.     (gnus-simplify-subject (nntp-header-subject it) 're-only)))
  157.      )
  158.    reverse)
  159.   )
  160.  
  161. ;; For backward compatibility with GNUS 3.13
  162. (if (not (fboundp 'gnus-sortable-date))
  163.     (fset 'gnus-sortable-date 'gnus-comparable-date))
  164.  
  165. (defun gnus-Subject-sort-by-date (reverse)
  166.   "Sort *Subject* buffer by posted date.  Argument REVERSE means
  167. reverse order."
  168.   (interactive "P")
  169.   (gnus-Subject-keyed-sort-subjects
  170.    'string<
  171.    (function
  172.     (lambda (it)
  173.       (gnus-sortable-date (nntp-header-date it))))
  174.    reverse)
  175.   )
  176.  
  177. Cheers,
  178.  
  179. Marc
  180.  
  181. --
  182. Marc Andreessen
  183. Software Development Group
  184. National Center for Supercomputing Applications
  185. marca@ncsa.uiuc.edu
  186.