From: Batuhan Taskaya Date: Tue, 16 Nov 2021 02:38:40 +0000 (+0300) Subject: black/parser: optimize deepcopying nodes (#2611) X-Git-Url: https://git.madduck.net/etc/vim.git/commitdiff_plain/d7b091e762121ee38ca313ab25006abf4723d203?ds=inline black/parser: optimize deepcopying nodes (#2611) The implementation of the new backtracking logic depends heavily on deepcopying the current state of the parser before seeing one of the new keywords, which by default is an very expensive operations. On my system, formatting these 3 files takes 1.3 seconds. ``` $ touch tests/data/pattern_matching_*; time python -m black -tpy310 tests/data/pattern_matching_* 19ms All done! ✨ 🍰 ✨ 3 files left unchanged. python -m black -tpy310 tests/data/pattern_matching_* 2,09s user 0,04s system 157% cpu 1,357 total ``` which can be optimized 3X if we integrate the existing copying logic (`clone`) to the deepcopy system; ``` $ touch tests/data/pattern_matching_*; time python -m black -tpy310 tests/data/pattern_matching_* 1ms All done! ✨ 🍰 ✨ 3 files left unchanged. python -m black -tpy310 tests/data/pattern_matching_* 0,66s user 0,02s system 147% cpu 0,464 total ``` This still might have some potential, but that would be way trickier than this initial patch. --- diff --git a/src/blib2to3/pytree.py b/src/blib2to3/pytree.py index 7843467..001652d 100644 --- a/src/blib2to3/pytree.py +++ b/src/blib2to3/pytree.py @@ -52,7 +52,7 @@ def type_repr(type_num: int) -> Union[Text, int]: return _type_reprs.setdefault(type_num, type_num) -_P = TypeVar("_P") +_P = TypeVar("_P", bound="Base") NL = Union["Node", "Leaf"] Context = Tuple[Text, Tuple[int, int]] @@ -109,6 +109,9 @@ class Base(object): """ raise NotImplementedError + def __deepcopy__(self: _P, memo: Any) -> _P: + return self.clone() + def clone(self: _P) -> _P: """ Return a cloned (deep) copy of self. diff --git a/tests/data/pattern_matching_extras.py b/tests/data/pattern_matching_extras.py index b17922d..614e66a 100644 --- a/tests/data/pattern_matching_extras.py +++ b/tests/data/pattern_matching_extras.py @@ -1,3 +1,5 @@ +import match + match something: case [a as b]: print(b) @@ -7,3 +9,21 @@ match something: print(b) case Point(int() as x, int() as y): print(x, y) + + +match = 1 +case: int = re.match(something) + +match re.match(case): + case type("match", match): + pass + case match: + pass + + +def func(match: case, case: match) -> case: + match Something(): + case another: + ... + case func(match, case): + ...