[PATCH 5 of 5 V2] dirstate.status: assign members one by one instead of unpacking the tuple
Siddharth Agarwal
sid0 at fb.com
Thu May 29 18:19:20 CDT 2014
# HG changeset patch
# User Siddharth Agarwal <sid0 at fb.com>
# Date 1401249736 25200
# Tue May 27 21:02:16 2014 -0700
# Node ID c862f5d80f1005d61025dc9bc76f4243744a01f1
# Parent 6bc322288121913762c877241a3a95ed4c1ada75
dirstate.status: assign members one by one instead of unpacking the tuple
With this patch, hg status and hg diff regain their previous speed.
The following tests are run against a working copy with over 270,000 files.
Here, 'before' means without this or the previous patch applied.
Note that in this case `hg perfstatus` isn't representative since it doesn't
take dirstate parsing time into account.
$ time hg status # best of 5
before: 2.03s user 1.25s system 99% cpu 3.290 total
after: 2.01s user 1.25s system 99% cpu 3.261 total
$ time hg diff # best of 5
before: 1.32s user 0.78s system 99% cpu 2.105 total
after: 1.27s user 0.79s system 99% cpu 2.066 total
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -823,7 +823,18 @@
uadd(fn)
continue
- state, mode, size, time = dmap[fn]
+ # This is equivalent to 'state, mode, size, time = dmap[fn]' but not
+ # written like that for performance reasons. dmap[fn] is not a
+ # Python tuple in compiled builds. The CPython UNPACK_SEQUENCE
+ # opcode has fast paths when the value to be unpacked is a tuple or
+ # a list, but falls back to creating a full-fledged iterator in
+ # general. That is much slower than simply accessing and storing the
+ # tuple members one by one.
+ t = dmap[fn]
+ state = t[0]
+ mode = t[1]
+ size = t[2]
+ time = t[3]
if not st and state in "nma":
dadd(fn)
More information about the Mercurial-devel
mailing list