-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BUILD_SET followed by COMPARE_OP (in) can be optimized if all items are consts #50939
Comments
Just like we turn BUILD_LIST; COMPARE_OP (in) into a LOAD_CONST if all >>> dis.dis(lambda o: o in (1,2,3))
1 0 LOAD_FAST 0 (o)
3 LOAD_CONST 3 ((1, 2, 3))
6 COMPARE_OP 6 (in)
9 RETURN_VALUE
>>> dis.dis(lambda o: o in [1,2,3])
1 0 LOAD_FAST 0 (o)
3 LOAD_CONST 3 ((1, 2, 3))
6 COMPARE_OP 6 (in)
9 RETURN_VALUE
>>> dis.dis(lambda o: o in {1,2,3})
1 0 LOAD_FAST 0 (o)
3 LOAD_CONST 0 (1)
6 LOAD_CONST 1 (2)
9 LOAD_CONST 2 (3)
12 BUILD_SET 3
15 COMPARE_OP 6 (in)
18 RETURN_VALUE |
It's certainly possible to do so, do you have a patch? |
Antoine, I hope to have some time to write a patch for this in the |
+1 |
Ugh, I haven't had the time to work on this, just wanted to note that this now applies to 2.7 as well since set literals were backported. |
Attaching a probably over-simplistic attempt at this patch, against the py3k branch. This patch attempts to extend the replacement of so that it also replaces: i.e. using a tuple, not a frozenset (on the grounds that the "in" conditions should at least still work); caveat: I'm relatively new to the innards of this code. With this patch:
>>> dis.dis(lambda o: o in {1,2,3})
1 0 LOAD_FAST 0 (o)
3 LOAD_CONST 3 ((1, 2, 3))
6 COMPARE_OP 6 (in)
9 RETURN_VALUE
but:
>>> dis.dis(lambda o: o in {1,2,3,3,2,1})
1 0 LOAD_FAST 0 (o)
3 LOAD_CONST 3 ((1, 2, 3, 3, 2, 1))
6 COMPARE_OP 6 (in)
9 RETURN_VALUE Is it worth me working on a rewrite to use a frozenset. Hope this is helpful |
David, I think it should use frozen set since doing it this way could actually increase the time the operation takes (which is certainly not our goal!). Plus marshall.c already handles frozenset, so I don't think it's that much more work. |
Alex: good point - thanks! Attaching updated version of the patch (again, against py3k, likewise, I'm somewhat new to this code, so I may have missed things) With this:
>>> dis.dis(lambda o: o in {1,2,3})
1 0 LOAD_FAST 0 (o)
3 LOAD_CONST 3 (frozenset({1, 2, 3}))
6 COMPARE_OP 6 (in)
9 RETURN_VALUE
>>> dis.dis(lambda o: o in {1,2,3,3,2,1})
1 0 LOAD_FAST 0 (o)
3 LOAD_CONST 3 (frozenset({1, 2, 3}))
6 COMPARE_OP 6 (in)
9 RETURN_VALUE
and the tuple/list cases are again as in the original comment. I'm in the process of running the full test suite. |
The patch looks more or less right to me (but I'm far from an expert). It needs tests in the peephole tests though. |
Thanks for looking at the patch. Attached is an updated version (again against py3k) which adds tests to Lib/test/test_peepholer.py, for both the new folding away of BUILD_SET, and for the pre-existing folding of BUILD_LIST (which didn't seem to have tests). Hopefully these look good. One possible worry I had with them is with the string comparison against repr(various frozensets) for the disassembly of the bytecode: the new tests thus assume that the ordering of the repr of a frozenset is constant. Is this a reasonable assumption, or should the choice of test items be changed to ones with more robust ordering in their repr() string? |
No, you can't rely on the repr of a frozenset with multiple items. You should find another way of testing (if you are brave you could match the "frozenset(...)" with a regex and eval() it). Some comments on the patch:
|
Thanks for the suggestions. Attached is a revised version of the patch.
The existing tests don't use assertIn/assertNotIn; I'm working on a patch for that, but I'll file that as a separate bug. |
Nice looking patch. |
The patch was committed in r77543 (py3k), thank you! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: