Subject: 24.3.50; [PATCH] parse-time-string performance

From: Andreas Politz <[email-masked]>
Date: Wed, 03 Jul 2013 03:21:09 +0200

I think parse-time-string's performance can be increased significantly
by the attached patch, which replaces `parse-time-string-chars' with
something more sensible.  This function gets called at least once for
every character of the date being parsed, e.g. ~100,000 times in a 3000
article gnus buffer.

I made a comparisons with 3000 dates extracted from mail articles like
this, which seems to suggest some improvement.  I hope that it is also
correct.

(progn
  (garbage-collect)
  (benchmark 100
             '(dolist (d dates)
                (parse-time-string d))))

status quo: 41.547726s (5.333477s in 28 GCs)
patched   : 10.132069s (0.389833s in 2 GCs)

-ap

=== modified file 'lisp/calendar/parse-time.el'
*** lisp/calendar/parse-time.el	2013-01-01 09:11:05 +0000
--- lisp/calendar/parse-time.el	2013-07-03 00:57:29 +0000
***************
*** 49,63 ****
  (defsubst digit-char-p (char)
    (aref parse-time-digits char))
  
! (defsubst parse-time-string-chars (char)
!   (save-match-data
!     (let (case-fold-search str)
!       (cond ((eq char ?+) 1)
! 	    ((eq char ?-) -1)
! 	    ((eq char ?:) ?d)
! 	    ((string-match "[[:upper:]]" (setq str (string char))) ?A)
! 	    ((string-match "[[:lower:]]" str) ?a)
! 	    ((string-match "[[:digit:]]" str) ?0)))))
  
  (put 'parse-error 'error-conditions '(parse-error error))
  (put 'parse-error 'error-message "Parsing error")
--- 49,64 ----
  (defsubst digit-char-p (char)
    (aref parse-time-digits char))
  
! (defun parse-time-string-chars (char)
!   (cond ((eq char ?+) 1)
!         ((eq char ?-) -1)
!         ((eq char ?:) ?d)
!         ((memq char '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)) ?0)
!         ((not (eq (upcase char)
!                   (downcase char)))
!          (cond
!           ((eq char (upcase char)) ?A)
!           (t ?a)))))
  
  (put 'parse-error 'error-conditions '(parse-error error))
  (put 'parse-error 'error-message "Parsing error")

In GNU Emacs 24.3.50.2 (x86_64-unknown-linux-gnu, GTK+ Version 2.20.1)
 of 2013-05-23 on luca
Bzr revision: 112687 [email-masked]
Windowing system distributor `The X.Org Foundation', version 11.0.10707000
System Description:	Debian GNU/Linux 6.0.7 (squeeze)

Important settings:
  value of $LC_COLLATE: C
  value of $LC_MESSAGES: C
  value of $LANG: de_DE.UTF-8
  locale-coding-system: utf-8-unix
  default enable-multibyte-characters: t

Major mode: Emacs-Lisp

Minor modes in effect:
  diff-auto-refine-mode: t
  desktop-save-mode: t
  workgroups-mode: t
  ispell-track-input-method: t
  recentf-mode: t
  show-paren-mode: t
  yas-global-mode: t
  yas-minor-mode: t
  window-numbering-mode: t
  shell-dirtrack-mode: t
  scroll-other-window-mode: t
  savehist-mode: t
  TeX-PDF-mode: t
  ekey-mode: t
  winner-mode: t
  eldoc-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent input:
C-/ C-/ C-/ M-m C-y C-M-k C-u C-c C-c <switch-frame> 
C-M-a C-M-f C-x C-e <switch-frame> C-u C-c C-c <switch-frame> 
C-x 0 C-x C-e C-x o C-x b n e w - g <return> <switch-frame> 
<switch-frame> <switch-frame> C-, w d i f f <return> 
M-x d i f f - b u f f <return> <return> C-/ C-/ C-/ 
C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ 
C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ 
C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ 
C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ 
C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ 
C-/ C-/ C-/ C-/ C-/ C-x C-s C-g C-/ C-/ C-/ C-/ C-/ 
C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ 
C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ 
C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ 
C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-/ C-g 
C-/ C-/ C-/ C-/ C-/ C-/ M-x M-x <return> <return> C-x 
o C-v C-l C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n 
C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-n C-p C-p 
C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p 
C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p 
C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p C-p 
C-p C-p C-p C-p C-p C-p C-p C-p <switch-frame> <switch-frame> 
C-x o C-x 1 C-x m C-x k <return> M-x r e p o r t - 
e m a <tab> b u g <return>

Recent messages:
Redo! [2 times]
Undo! [2 times]
No further undo information [44 times]
Quit
Redo! [6 times]
View mode: type C-h for help, h for commands, q to quit.
End of buffer [3 times]
Beginning of buffer [10 times]
Auto-saving...done
Source file `/home/politza/src/emacs/trunk/lisp/gnus/nnir.el' newer than byte-compiled file

Load-path shadows:
/home/politza/.emacs.d/elpa/yasnippet-0.8.0/dropdown-list hides /home/politza/.emacs.d/plugins/yasnippet-0.6.1c/dropdown-list
/home/politza/.emacs.d/elpa/yasnippet-0.8.0/yasnippet hides /home/politza/.emacs.d/plugins/yasnippet-0.6.1c/yasnippet
/home/politza/.emacs.d/plugins/tblc hides /home/politza/.emacs.d/plugins/tblc/tblc
/home/politza/.emacs.d/plugins/haskell-mode/haskell-cabal hides /home/politza/.emacs.d/plugins/haskell/haskell-cabal
/home/politza/.emacs.d/plugins/haskell-mode/haskell-decl-scan hides /home/politza/.emacs.d/plugins/haskell/haskell-decl-scan
/home/politza/.emacs.d/plugins/haskell-mode/haskell-doc hides /home/politza/.emacs.d/plugins/haskell/haskell-doc
/home/politza/.emacs.d/plugins/haskell-mode/ghc-core hides /home/politza/.emacs.d/plugins/haskell/ghc-core
/home/politza/.emacs.d/plugins/haskell-mode/haskell-mode hides /home/politza/.emacs.d/plugins/haskell/haskell-mode
/home/politza/.emacs.d/plugins/haskell-mode/haskell-c hides /home/politza/.emacs.d/plugins/haskell/haskell-c
/home/politza/.emacs.d/plugins/haskell-mode/haskell-indentation hides /home/politza/.emacs.d/plugins/haskell/haskell-indentation
/home/politza/.emacs.d/plugins/haskell-mode/haskell-site-file hides /home/politza/.emacs.d/plugins/haskell/haskell-site-file
/home/politza/.emacs.d/plugins/haskell-mode/haskell-ghci hides /home/politza/.emacs.d/plugins/haskell/haskell-ghci
/home/politza/.emacs.d/plugins/haskell-mode/inf-haskell hides /home/politza/.emacs.d/plugins/haskell/inf-haskell
/home/politza/.emacs.d/plugins/haskell-mode/haskell-indent hides /home/politza/.emacs.d/plugins/haskell/haskell-indent
/home/politza/.emacs.d/plugins/haskell-mode/haskell-hugs hides /home/politza/.emacs.d/plugins/haskell/haskell-hugs
/home/politza/.emacs.d/plugins/haskell-mode/haskell-font-lock hides /home/politza/.emacs.d/plugins/haskell/haskell-font-lock
/home/politza/.emacs.d/plugins/haskell-mode/haskell-simple-indent hides /home/politza/.emacs.d/plugins/haskell/haskell-simple-indent
/home/politza/.emacs.d/plugins/jedi/scratch hides /home/politza/.emacs.d/plugins/ewm/scratch
/home/politza/.emacs.d/elpa/company-0.6.8/.dir-locals hides /home/politza/.emacs.d/plugins/el-get/.dir-locals
/home/politza/.emacs.d/plugins/imenu hides /home/politza/src/emacs/trunk/lisp/imenu
/home/politza/.emacs.d/plugins/term hides /home/politza/src/emacs/trunk/lisp/term
/home/politza/.emacs.d/plugins/python/python/python hides /home/politza/src/emacs/trunk/lisp/progmodes/python
/home/politza/src/emacs/trunk/lisp/net/shr hides /home/politza/src/emacs/trunk/lisp/gnus/shr
/home/politza/.emacs.d/elpa/company-0.6.8/.dir-locals hides /home/politza/src/emacs/trunk/lisp/gnus/.dir-locals
/home/politza/src/emacs/trunk/lisp/net/shr-color hides /home/politza/src/emacs/trunk/lisp/gnus/shr-color
/home/politza/src/emacs/trunk/lisp/net/xesam hides /home/politza/src/emacs/trunk/lisp/obsolete/xesam
/home/politza/.emacs.d/plugins/python/python/sym-comp hides /home/politza/src/emacs/trunk/lisp/obsolete/sym-comp
/home/politza/.emacs.d/plugins/matlab/matlab hides /usr/share/emacs-snapshot/site-lisp/emacs-goodies-el/matlab
/home/politza/.emacs.d/plugins/boxquote hides /usr/share/emacs-snapshot/site-lisp/emacs-goodies-el/boxquote
/home/politza/.emacs.d/plugins/bm hides /usr/share/emacs-snapshot/site-lisp/emacs-goodies-el/bm
/home/politza/.emacs.d/plugins/haskell-mode/haskell-decl-scan hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-decl-scan
/home/politza/.emacs.d/plugins/haskell-mode/haskell-c hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-c
/home/politza/.emacs.d/plugins/haskell-mode/haskell-ghci hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-ghci
/home/politza/.emacs.d/plugins/haskell-mode/haskell-doc hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-doc
/home/politza/.emacs.d/plugins/haskell-mode/haskell-indent hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-indent
/home/politza/.emacs.d/plugins/haskell-mode/haskell-mode hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-mode
/home/politza/.emacs.d/plugins/haskell-mode/haskell-hugs hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-hugs
/home/politza/.emacs.d/plugins/haskell-mode/haskell-site-file hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-site-file
/home/politza/.emacs.d/plugins/haskell-mode/haskell-cabal hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-cabal
/home/politza/.emacs.d/plugins/haskell-mode/inf-haskell hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/inf-haskell
/home/politza/.emacs.d/plugins/haskell-mode/haskell-font-lock hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-font-lock
/home/politza/.emacs.d/plugins/haskell-mode/haskell-simple-indent hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-simple-indent
/home/politza/.emacs.d/plugins/haskell-mode/haskell-indentation hides /usr/share/emacs-snapshot/site-lisp/haskell-mode/haskell-indentation
/home/politza/.emacs.d/elpa/pdf-tools-0.2alpha1/pdf-links hides /home/politza/.emacs.d/working/pdf-tools/lisp/pdf-links
/home/politza/.emacs.d/elpa/pdf-tools-0.2alpha1/pdf-render hides /home/politza/.emacs.d/working/pdf-tools/lisp/pdf-render
/home/politza/.emacs.d/elpa/pdf-tools-0.2alpha1/pdf-occur hides /home/politza/.emacs.d/working/pdf-tools/lisp/pdf-occur
/home/politza/.emacs.d/elpa/pdf-tools-0.2alpha1/pdf-history hides /home/politza/.emacs.d/working/pdf-tools/lisp/pdf-history
/home/politza/.emacs.d/elpa/pdf-tools-0.2alpha1/pdf-tools hides /home/politza/.emacs.d/working/pdf-tools/lisp/pdf-tools
/home/politza/.emacs.d/elpa/pdf-tools-0.2alpha1/pdf-outline hides /home/politza/.emacs.d/working/pdf-tools/lisp/pdf-outline
/home/politza/.emacs.d/elpa/pdf-tools-0.2alpha1/pdf-misc hides /home/politza/.emacs.d/working/pdf-tools/lisp/pdf-misc
/home/politza/.emacs.d/elpa/pdf-tools-0.2alpha1/pdf-info hides /home/politza/.emacs.d/working/pdf-tools/lisp/pdf-info
/home/politza/.emacs.d/elpa/pdf-tools-0.2alpha1/pdf-util hides /home/politza/.emacs.d/working/pdf-tools/lisp/pdf-util
/home/politza/.emacs.d/elpa/pdf-tools-0.2alpha1/pdf-annot hides /home/politza/.emacs.d/working/pdf-tools/lisp/pdf-annot
/home/politza/.emacs.d/elpa/pdf-tools-0.2alpha1/pdf-isearch hides /home/politza/.emacs.d/working/pdf-tools/lisp/pdf-isearch

Features:
(shadow emacsbug bbdb-message sendmail nnir diff dired-aux whitespace
diff-mode vc ibuf-ext imenu-outline ispell quail cc-langs cc-mode
cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars
cc-defs find-dired debug shr-color color mm-archive misearch
multi-isearch reposition apropos calc-arith calc-misc calccomp calc-aent
calc-alg calc-units calc-ext calc-menu calc calc-loaddefs calc-macs
benchmark sort smiley gnus-cite mail-extr gnus-bcklg shr gnus-async qp
gnus-ml disp-table elp nndraft nnmh utf-7 gnutls network-stream starttls
nnfolder bbdb-gnus nnnil gnus-agent gnus-srvr gnus-score score-mode
nnvirtual gnus-msg gnus-art mm-uu mml2015 epg-config mm-view mml-smime
smime dig mailcap nntp gnus-cache hi-lock tex-buf reftex-dcr reftex-auc
font-latex vc-git pdftk-outline vc-bzr dired-eshell vc-dispatcher vc-svn
emacs-customizations nogroup-customizations wp-customizations
view-customizations tex-customizations reftex-customizations
reftex-miscellaneous-configurations-customizations
reftex-label-support-customizations
reftex-referencing-labels-customizations
reftex-defining-label-environments-customizations AUCTeX-customizations
preview-customizations preview-latex-customizations
preview-appearance-customizations TeX-parse-customizations
TeX-file-customizations TeX-command-customizations
TeX-view-customizations LaTeX-customizations LaTeX-macro-customizations
LaTeX-math-customizations LaTeX-indentation-customizations
table-customizations table-hooks-customizations outlines-customizations
programming-customizations tools-customizations vc-customizations
log-edit-customizations semantic-customizations makefile-customizations
etags-customizations ediff-customizations diff-mode-customizations
languages-customizations elpy-customizations matlab-customizations
sh-customizations python-customizations rx haskell-customizations
c-customizations asm-customizations multimedia-customizations
image-customizations help-customizations ekey-customizations
info-lookup-customizations info-customizations customize-customizations
custom-buffer-customizations apropos-customizations files-customizations
uniquify-customizations uniquify sunrise-customizations
recentf-customizations find-file-customizations backup-customizations
faces-customizations highlight-symbol-customizations
font-lock-customizations hi-lock-customizations facemenu-customizations
external-customizations server-customizations processes-customizations
shell-customizations proced-customizations gud-customizations
tooltip-customizations grep-customizations compilation-customizations
next-error-customizations comint-customizations SQL-customizations
man-customizations environment-customizations xterm-customizations
windows-customizations winner-customizations minibuffer-customizations
savehist-customizations completion-spelling lib-string
menu-customizations keyboard-customizations chistory-customizations
initialization-customizations frames-customizations
ediff-window-customizations desktop-customizations desktop
dired-customizations dired-x-customizations dired-x
dired-details-customizations editing-customizations
yasnippet-customizations paragraphs-customizations
matching-customizations paren-matching-customizations
paren-showing-customizations isearch-customizations
bookmark-customizations killing-customizations indent-customizations
fill-customizations emulations-customizations
editing-basics-customizations development-customizations
lisp-customizations re-builder-customizations
inferior-lisp-customizations ielm-customizations ert-customizations
edebug-customizations bytecomp-customizations advice-customizations
internal-customizations alloc-customizations extensions-customizations
eldoc-customizations cust-print-customizations data-customizations
save-place-customizations convenience-customizations
diminish-customizations diminish iedit-customizations
imenu-tree-customizations tags-tree-customizations
company-customizations workgroups-customizations workgroups bookmark pp
window-numbering-customizations pabbrev-customizations
kmacro-customizations imenu-customizations ibuffer-customizations
ibuf-macs hl-line-customizations hippie-expand-customizations
file-cache-customizations ffap-customizations completion-customizations
iswitchb-customizations browse-kill-ring-customizations
auto-revert-customizations auto-insert-customizations
Buffer-menu-customizations comm-customizations tramp-customizations
browse-url-customizations applications-customizations
mediawiki-customizations w3m-customizations package-customizations
mail-customizations bbdb-customizations bbdb-sendmail-customizations
bbdb-mua-customizations bbdb-mua bbdb-com crm bbdb
smtpmail-customizations sendmail-customizations gnus-customizations
nnmail-customizations gnus-summary-customizations
gnus-thread-customizations gnus-summary-various-customizations
gnus-summary-sort-customizations gnus-summary-marks-customizations
gnus-summary-maneuvering-customizations
gnus-summary-format-customizations gnus-summary-exit-customizations
gnus-sum gnus-group gnus-undo gnus-start gnus-spec gnus-win
gnus-start-customizations gnus-server-customizations
gnus-message-customizations message-customizations
message-various-customizations message-buffers-customizations
gnus-group-customizations gnus-group-visual-customizations
gnus-nnimap-format nnimap nnmail gnus-int mail-source message rfc822 mml
mml-sec mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045
ietf-drums mailabbrev gmm-utils mailheader parse-time tls utf7 netrc
nnoo gnus gnus-ems nnheader mail-utils gnus-files-customizations
gnus-newsrc-customizations gnus-exit-customizations
gnus-article-customizations gnus-article-hiding-customizations
ispell-customizations eshell-customizations eshell-module-customizations
eshell-smart-customizations eshell-hist-customizations
eshell-mode-customizations edebug doc-view-customizations
pdf-tools-customizations pdf-annot-customizations
pdf-links-customizations pdf-isearch-customizations pdf-annot pdf-occur
pdf-history pdf-outline pdf-links pdf-isearch pdf-misc imenu pdf-attach
pdf-info tq pdf-render pdf-tools pdf-util gnus-range tablist
tablist-filter pcase semantic/wisent/comp semantic/wisent
semantic/wisent/wisent semantic/util-modes semantic/util semantic
semantic/tag semantic/lex semantic/fw mode-local cedet doc-view
jka-compr image-mode calendar-customizations org-customizations
org-structure-customizations org-plain-lists-customizations
org-edit-structure-customizations org-startup-customizations
org-link-customizations org-latex-customizations
org-appearance-customizations holidays-customizations
calculator-customizations calc-customizations server recentf tree-widget
.autoload paren yasnippet dropdown-list help-mode window-numbering w3m
browse-url timezone w3m-hist w3m-e23 w3m-ccl ccl w3m-fsf w3m-favicon
w3m-image w3m-proc w3m-util view tramp tramp-compat tramp-loaddefs
trampver shell track-last-window scroll-other-window saveplace savehist
reftex reftex-vars pabbrev org ob-tangle ob-ref ob-lob ob-table
org-footnote org-src ob-comint ob-keys org-pcomplete org-list org-faces
org-entities noutline outline org-version ob-emacs-lisp ob org-compat
org-macs ob-eval org-loaddefs format-spec find-func cal-menu calendar
cal-loaddefs lib-edit lib-window lib-isearch lib-buffer reveal iswitchb
lib-basic lib-lispext latex easy-mmode tex-style tex dbus xml tex-site
auto-loads info-look info ibuffer hippie-exp grep compile filecache
edit-minibuffer eldoc-eval pcomplete esh-var esh-io esh-cmd esh-opt
esh-ext esh-proc esh-arg esh-groups eshell esh-module esh-mode esh-util
ekey assoc dired-details+ warnings dired dired-details
cool-prefix-bindings winner lib-kbd comint-history comint ansi-color
ring browse-kill-ring advice anticus edmacro kmacro derived cl-macs gv
ffap thingatpt url-parse auth-source eieio byte-opt bytecomp
byte-compile cconv gnus-util mm-util mail-prsvr password-cache url-vars
eldoc help-fns cus-edit easymenu cus-start cus-load wid-edit cl nadvice
cl-lib bbdb-loaddefs cl-format-autoloads company-autoloads
eldoc-eval-autoloads pdf-tools-autoloads yasnippet-autoloads package
time-date tooltip ediff-hook vc-hooks lisp-float-type mwheel x-win x-dnd
tool-bar dnd fontset image regexp-opt fringe tabulated-list newcomment
lisp-mode register page menu-bar rfn-eshadow timer select scroll-bar
mouse jit-lock font-lock syntax facemenu font-core frame cham georgian
utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese case-table epa-hook jka-cmpr-hook help simple abbrev
minibuffer loaddefs button faces cus-face macroexp files text-properties
overlay sha1 md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote make-network-process dbusbind inotify
dynamic-setting system-font-setting font-render-setting move-toolbar gtk
x-toolkit x multi-tty emacs)