OPT-13 Pre-load functions for binary operations to known types#
Background#
CPython will compile complex mathematical operations into opcodes based on operator precedence and stack. All binary operations and inplace operations (Add, subtract, divide, floor divide, power), take 2 arguments, the left and right hand objects.
E.g.
c = a + b
In this example, the value of a and b is loaded (from LOAD_FAST, LOAD_NAME, or LOAD_GLOBAL depending on the scoping) and the reference count is incremented.
The binary add operation then calculates a new value and decrements the reference to a
and b
.
The API for working out the correct magic-method to call is in CPython’s abstract API.
For example, the +
operator will call PyNumber_Add(a, b)
.
This will resolve to:
IF
b
is a subtype ofa
and it implements that slot, use thatIf
a
has that slot implemented, use thatIf
b
has that slot implemented, use that
For each of these, the call can return a singleton string, Py_NotImplemented
.
There is also another branch for inplace operators, where if the inplace slot is not implemented, it will fall back to the regular slot.
Solution#
If the left-hand and right-hand operands are both known types at compile-time, Pyjion will work out the logic of which slot has preference at compile time and emit a method call to the implementation of that slot.
Gains#
Add binary operations where left and right are known types are faster.
Edge-cases#
None
Further Enhancements#
Determine more types through profiling.
Configuration#
This optimization is enabled at level 1 by default. See Optimizations for help on changing runtime optimization settings.