Repository navigation
Performance Overhead in Ternary Operator Due to Value Loading vs Constant Loading #127685
Copy link
Copy link
Closed as not planned
Closed as not planned
Copy link
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagePerformance or resource usagetype-featureA feature request or enhancementA feature request or enhancement
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Dec 6, 2024 cc @markshannon
- addedperformancePerformance or resource usagePerformance or resource usagetype-featureA feature request or enhancementA feature request or enhancementinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)and removedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Dec 6, 2024 Question: is this the result with a DEBUG build? or PGO build?
@picnixz This is not a special build, but just python3. 12 from uv. Python version -- 3.12.7
I think that this is a known problem (but I cannot find the needed issue).
Reacted by Kirill PodoprigoraQuestion: is this the result with a DEBUG build? or PGO build?
PGO/LTO/BOLT/Debug builds doesn't affect the actual bytecode construction.
There's no more a
RETURN_CONSTopcode, so I don't think this is an issue, and this in fact is a duplicate of #121246.
Nevertheless, thank you for the report, Shamil.FYI, here's the bytecode of
testandtest2functions on 3.14 branch, which in fact are identical:eclips4@nixos ~/p/p/cpython (remove-ast-optimizer)> ./python Python 3.14.0a2+ (heads/remove-ast-optimizer-dirty:7ce21584115, Jan 1 1980, 00:00:00) [GCC 13.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import dis >>> def test(var): ... if var: ... return True ... else: ... return False ... >>> dis.dis(test) 1 RESUME 0 2 LOAD_FAST 0 (var) TO_BOOL POP_JUMP_IF_FALSE 2 (to L1) 3 LOAD_CONST 0 (True) RETURN_VALUE 5 L1: LOAD_CONST 1 (False) RETURN_VALUE >>> def test2(var): ... return True if var else False ... >>> dis.dis(test2) 1 RESUME 0 2 LOAD_FAST 0 (var) TO_BOOL POP_JUMP_IF_FALSE 2 (to L1) LOAD_CONST 0 (True) RETURN_VALUE L1: LOAD_CONST 1 (False) RETURN_VALUE >>>
Reacted by Shamil
Metadata
Metadata
Assignees
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagePerformance or resource usagetype-featureA feature request or enhancementA feature request or enhancement
Bug report
Bug description:
A performance bottleneck has been identified in CPython's bytecode generation for ternary expressions compared to traditional if-else statements, specifically related to how constants are loaded.
Bytecode Comparison
Traditional If-Else (Optimized)
Bytecode:
Ternary Operator (Less Efficient)
Bytecode:
Problem
In the ternary operator version:
LOAD_CONSTis used instead of the more efficientRETURN_CONSTRETURN_VALUEinstructionRecommendation
Modify the bytecode generation for ternary expressions to:
RETURN_CONSTwhen returning boolean constantsAdditional Notes
CPython versions tested on:
3.12
Operating systems tested on:
Linux