# HG changeset patch # User Jun Wu <qu...@fb.com> # Date 1487467423 28800 # Sat Feb 18 17:23:43 2017 -0800 # Node ID 6f57ef05c74567db95f42426499640ad29bc878f # Parent deb48622b857d621606a1cdda4adc868b1c663d4 # Available At https://bitbucket.org/quark-zju/hg-draft # hg pull https://bitbucket.org/quark-zju/hg-draft -r 6f57ef05c745 smartset: use native set operations as fast paths
For set operations like "&" and "-", where we know both basesets have their sets ready, and the first set is sorted, use the native Python set operations as a fast path. Note: "+" is not optimized as that will break the ordering. This leads to noticeable improvements on performance: revset | before | after | delta ---------------------------------------------------------------- draft() & draft() & draft() & draft() | 776 | 477 | -39% draft() + draft() + draft() + draft() | 2849 | 2864 | draft() - draft() + draft() - draft() | 943 | 240 | -75% draft() - draft() - draft() - draft() | 557 | 197 | -64% (time measured in microseconds) diff --git a/mercurial/smartset.py b/mercurial/smartset.py --- a/mercurial/smartset.py +++ b/mercurial/smartset.py @@ -172,5 +172,5 @@ class baseset(abstractsmartset): [[0, 4, 6, 7, 3, 5], [6, 7], [0, 4]] >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]] - ['addset', 'filteredset', 'filteredset'] + ['addset', 'baseset', 'baseset'] Construct by a list-like: @@ -192,10 +192,10 @@ class baseset(abstractsmartset): ['addset', 'filteredset', 'filteredset'] - With sort(): + With sort(), set optimization could be used: >>> xs.sort(reverse=True) >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]] [[7, 6, 4, 0, 5, 3], [7, 6], [4, 0]] >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]] - ['addset', 'filteredset', 'filteredset'] + ['addset', 'baseset', 'baseset'] >>> ys.sort() @@ -203,5 +203,5 @@ class baseset(abstractsmartset): [[7, 6, 4, 0, 3, 5], [7, 6], [4, 0]] >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]] - ['addset', 'filteredset', 'filteredset'] + ['addset', 'baseset', 'baseset'] """ def __init__(self, data=(), datarepr=None, istopo=False): @@ -323,4 +323,20 @@ class baseset(abstractsmartset): return None + def _fastsetop(self, other, op): + # try to use native set operations as fast paths + if (type(other) is baseset and '_set' in other.__dict__ and '_set' in + self.__dict__ and self._ascending is not None): + s = baseset(data=getattr(self._set, op)(other._set)) + s._ascending = self._ascending + else: + s = getattr(super(baseset, self), op)(other) + return s + + def __and__(self, other): + return self._fastsetop(other, '__and__') + + def __sub__(self, other): + return self._fastsetop(other, '__sub__') + def __repr__(self): d = {None: '', False: '-', True: '+'}[self._ascending] _______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel