You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What is the advantage of having a forward version or a jump-if-exhausted version when the vast majority of executions of the opcode will be (backwards, jump-if-not-exhausted)? Is that symmetry worth the extra code in ceval loop?
I proposed a similar idea (opcode FOR_NEXT) in the discussion for #71314. At that time it was rejected because it makes the relation between Python code and the generated bytecode less straightforward. Seems the bar is lower now, so I considered to return to this.
I have not implemented it because:
It would require rewriting the code for the frame.f_lineno setter, which was already too complicated and brittle.
It would negatively affect the idiom: for x in a: break.
What if we specialized JUMP_BACKWARD to FOR_END_ADAPTIVE when targeted at FOR_ITER?
Then we get the same old readable unquickened bytecode but reduce the number of dispatches per for-loop for quickened bytecode? It would add cache entries to JUMP_BACKWARD, but perhaps we could eventually limit that to only the targeted-at-FOR_ITER cases.
@gahabana No changes have been made relating to this issue, so please open a new issue about a particular performance regression. Make sure to describe your operating system and how you installed python.
Activity
markshannon commentedon Apr 11, 2022
What about?
markshannon commentedon Apr 11, 2022
Also, we would like to decouple the sense (jumps on exhaustion like
FOR_ITER, or jumps when not exhausted likeEND_FOR) and the direction of the jump.markshannon commentedon Apr 11, 2022
If you only want one sense of jump, and to avoid the extra backwards branch, this should work (provided we have both a forward and backward version)
sweeneyde commentedon Apr 11, 2022
What is the advantage of having a forward version or a jump-if-exhausted version when the vast majority of executions of the opcode will be (backwards, jump-if-not-exhausted)? Is that symmetry worth the extra code in ceval loop?
sweeneyde commentedon Apr 12, 2022
Version with a JUMP_FORWARD to FOR_END, no FOR_ITER: #70016
Version with both a FOR_ITER and a FOR_END: #91472
serhiy-storchaka commentedon Apr 12, 2022
I proposed a similar idea (opcode
FOR_NEXT) in the discussion for #71314. At that time it was rejected because it makes the relation between Python code and the generated bytecode less straightforward. Seems the bar is lower now, so I considered to return to this.I have not implemented it because:
frame.f_linenosetter, which was already too complicated and brittle.for x in a: break.sweeneyde commentedon Apr 12, 2022
What if we specialized
JUMP_BACKWARDtoFOR_END_ADAPTIVEwhen targeted atFOR_ITER?Then we get the same old readable unquickened bytecode but reduce the number of dispatches per for-loop for quickened bytecode? It would add cache entries to
JUMP_BACKWARD, but perhaps we could eventually limit that to only the targeted-at-FOR_ITER cases.sweeneyde commentedon Apr 20, 2022
sweeneyde commentedon Apr 21, 2022
After merging up with main and re-running everything, I get these results:
Microbenchmarks:
Details
Pyperformance
All together in one table:
Details
Just looking at the FOR_ITER specialization:
Details
FOR_ITER specialization:
Just looking at the JUMP_BACKWARD specialization:
Details
JUMP_BACKWARD specialization:
Comparing the two:
Details
Specializing FOR_ITER --> Specializing JUMP_BACKWARD
[-]Replace JUMP+FOR_ITER with FOR_END[/-][+]Optimizing FOR_ITER[/+]sweeneyde commentedon Apr 24, 2022
Changing the issue title to be more general and include specializations without any FOR_END.
gahabana commentedon Jun 2, 2022
3.11 beta has much slower for loop with range then 3.10 or 3.9
this piece of code:
executes 20% slower with 3.11-dev, 3.11.0b1 as well as 3.11.0b3
I am not sure if this is related to above discussion
sweeneyde commentedon Jun 2, 2022
@gahabana No changes have been made relating to this issue, so please open a new issue about a particular performance regression. Make sure to describe your operating system and how you installed python.
[-]Optimizing FOR_ITER[/-][+]Optimizing FOR_ITER bytecode[/+]sweeneyde commentedon Jun 12, 2022
Some more microbenchmark (empty for-loop) results for other
FOR_ITERspecializations:STORE_FASTUNPACK_SEQUENCE(2)UNPACK_SEQUENCE(2)I collected opcode stats here a couple months ago, and I can't imagine much has changed since then.
If we manage to merge some version of #91713 (specializing list and range), I would think to do dict items and enumerate next.
GH-91432: Specialize FOR_ITER (GH-91713)
Revert 30935 defer bpo45162 to 312 (#94285)
GH-91432: Remove the iterator_exhausted_no_error label (GH-96517)
sweeneyde commentedon Sep 9, 2022
I'll go ahead and close this -- generators and such can be a separate issue.