Don't make redundant copies of the DFA
diff --git a/src/blib2to3/pgen2/parse.py b/src/blib2to3/pgen2/parse.py
index 4a23d538b4..a9dc11f39c 100644
--- a/src/blib2to3/pgen2/parse.py
+++ b/src/blib2to3/pgen2/parse.py
@@ -54,7 +54,7 @@ def stack_copy(
     stack: List[Tuple[DFAS, int, RawNode]]
 ) -> List[Tuple[DFAS, int, RawNode]]:
     """Nodeless stack copy."""
-    return [(copy.deepcopy(dfa), label, DUMMY_NODE) for dfa, label, _ in stack]
+    return [(dfa, label, DUMMY_NODE) for dfa, label, _ in stack]
 
 
 class Recorder:

`copy.deepcopy` is still the most expensive part (75/100 of the extra overhead introduced by the backtracking parser). I initially assumed it was mutable (since it was represented as a tuple of lists), but seems like we only use it as a basic table and don't mutate it anywhere in the code.

```
-t py39 (main):: Mean +- std dev: 7.21 ms +- 0.25 ms
-t py310 (this branch):: Mean +- std dev: 13.8 ms +- 0.6 ms
-t py310 (this branch):: Mean +- std dev: 7.98 ms +- 0.24 ms
```

This reduces the total overhead of the new backtracking parser from %91 to %11 (ran with tuned pyperf, but confirm please). 

We can even get rid of the `stack_copy` and just do a bare `parser.stack.copy()`, but I think it gives a nice abstraction and prevents leakage of any real nodes into the backtracking stack. In case anything goes wrong, and this does not seem to have an observable overhead. 