Patchwork obsolete: avoid slow, generic date parsing

login
register
mail settings
Submitter Gregory Szorc
Date Aug. 29, 2014, 4:19 p.m.
Message ID <cdc09971d47a40c0c2fc.1409329176@gps-mbp.local>
Download mbox | patch
Permalink /patch/5627/
State Accepted
Headers show

Comments

Gregory Szorc - Aug. 29, 2014, 4:19 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1409328044 -7200
#      Fri Aug 29 18:00:44 2014 +0200
# Node ID cdc09971d47a40c0c2fc850dc4e4da3492bfe05b
# Parent  f34449c49eda50266f9c9b1e86cd7c2cb0308d84
obsolete: avoid slow, generic date parsing

Simple profiling of `hg log -r .` revealed ~18,000 calls to
mercurial.i18n.gettext() on the author's repository. The
culprit was 3 _() calls in util.parsedate() multiplied by
~6000 obsmarkers originating from the parsing of obsmarkers.

Changing the obsmarker code to parse the stored format of
dates instead of going through a generic path eliminates these
gettext() lookups and makes `hg log -r .` execute ~10% faster
on the author's repo. The performance gain is proportional to
the number of obsmarkers.

The author attempted to patch util.parsedate() to avoid the
gettext() lookups. However, that code is whacky and the author
is jet lagged, so the approach was not attempted.
Matt Mackall - Aug. 30, 2014, 12:18 p.m.
On Fri, 2014-08-29 at 18:19 +0200, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@gmail.com>
> # Date 1409328044 -7200
> #      Fri Aug 29 18:00:44 2014 +0200
> # Node ID cdc09971d47a40c0c2fc850dc4e4da3492bfe05b
> # Parent  f34449c49eda50266f9c9b1e86cd7c2cb0308d84
> obsolete: avoid slow, generic date parsing

Queued for default, thanks.

Patch

diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -169,10 +169,11 @@  def _readmarkers(data):
                              % (mdsize, len(metadata)))
         off += mdsize
         meta = decodemeta(metadata)
         try:
-            date = util.parsedate(decodemeta(metadata).pop('date', '0 0'))
-        except util.Abort:
+            when, offset = decodemeta(metadata).pop('date', '0 0').split(' ')
+            date = float(when), int(offset)
+        except ValueError:
             date = (0., 0)
         parents = None
         if 'p2' in meta:
             parents = (meta.pop('p1', None), meta.pop('p2', None))