[PATCH 2 of 2] smartset: use native set operations as fast paths

Yuya Nishihara yuya at tcha.org
Sat Feb 18 03:27:51 EST 2017


On Fri, 17 Feb 2017 22:02:12 -0800, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu <quark at fb.com>
> # Date 1487396855 28800
> #      Fri Feb 17 21:47:35 2017 -0800
> # Node ID 1315d68b1dcf55247f51208608d139029eaae632
> # Parent  b32af6cafb9b958decb7ae0db7dd754aa5a5f883
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #              hg pull https://bitbucket.org/quark-zju/hg-draft -r 1315d68b1dcf
> smartset: use native set operations as fast paths
> 
> For cases where we know both basesets have their sets ready, use native
> Python set operations as a fast path.
> 
> This leads to noticeable improvements on some set operations:
> 
>   revset                                | before | after | after/before
>   ---------------------------------------------------------------------
>   draft() & draft() & draft() & draft() |   1123 |   818 | 0.72
>   draft() + draft() + draft() + draft() |   3288 |   817 | 0.25
>   draft() - draft() + draft() - draft() |   1277 |   551 | 0.43
>   draft() - draft() - draft() - draft() |    864 |   517 | 0.60
> 
>   (time unit: micro second)
> 
> diff --git a/mercurial/smartset.py b/mercurial/smartset.py
> --- a/mercurial/smartset.py
> +++ b/mercurial/smartset.py
> @@ -278,4 +278,28 @@ 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__):
> +            if op == '__add__':
> +                setop = 'union'
> +            else:
> +                setop = op  # __sub__ or __and__
> +            s = baseset(data=getattr(self._set, setop)(other._set),
> +                        istopo=self._istopo)
> +            s._ascending = self._ascending
> +        else:
> +            s = getattr(super(baseset, self), op)(other)
> +        return s
> +
> +    def __add__(self, other):
> +        return self._fastsetop(other, '__add__')
> +
> +    def __and__(self, other):
> +        return self._fastsetop(other, '__and__')
> +
> +    def __sub__(self, other):
> +        return self._fastsetop(other, '__sub__')

A baseset may be ordered. Native set ops are valid only in unordered context
(or when both sets have the same explicit ascending flag.)

Can you add some doctests?


More information about the Mercurial-devel mailing list