# HG changeset patch # User Chris Mason # Date 1150907328 25200 # Node ID 1e32e2fe8a677c391049d40b8794478976a0a914 # Parent 30c267cb4c2f010c6c3616cbc4177d91c9e000d4 Fix cold cache diff performance cold cache diff performance has regressed in two ways. localrepo.changes has optimizations for diffing against the working dir parent that expect node1 to be None. commands.revpair() usage means that commands.dodiff() never sends node1 == None. This is fixed in localrepo.changes by checking against the dirstate parents. In the non-dirstate parents case, localrepo.changes does a loop comparing files without first sorting the file names, leading to random access across the disk. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -618,7 +618,11 @@ class localrepository(object): del mf[fn] return mf - if node1: + compareworking = False + if not node1 or node1 == self.dirstate.parents()[0]: + compareworking = True + + if not compareworking: # read the manifest from node1 before the manifest from node2, # so that we'll hit the manifest cache if we're going through # all the revisions in parent->child order. @@ -635,7 +639,7 @@ class localrepository(object): self.dirstate.changes(files, match, show_ignored)) # are we comparing working dir against its parent? - if not node1: + if compareworking: if lookup: # do a full compare of any files that might have changed mf2 = mfmatches(self.dirstate.parents()[0]) @@ -658,11 +662,15 @@ class localrepository(object): deleted, unknown, ignored = [], [], [] mf2 = mfmatches(node2) - if node1: + if not compareworking: # flush lists from dirstate before comparing manifests modified, added = [], [] - for fn in mf2: + # make sure to sort the files so we talk to the disk in a + # reasonable order + mf2keys = mf2.keys() + mf2keys.sort() + for fn in mf2keys: if mf1.has_key(fn): if mf1[fn] != mf2[fn] and (mf2[fn] != "" or fcmp(fn, mf1)): modified.append(fn)