Skip to content

Commit f9fe331

Browse files
authored
[mypyc] Simplify comparison of tuple elements (#19396)
Got rid of unnecessary operations when comparing tuple elements returns a bit primitive. Example code: ``` def f(x: tuple[float], y: tuple[float]) -> bool: return x == y ``` IR before: ``` def f(x, y): x, y :: tuple[float] r0, r1 :: float r2 :: bit r3 :: object r4 :: i32 r5 :: bit r6, r7, r8 :: bool L0: r0 = x[0] r1 = y[0] r2 = r0 == r1 r3 = box(bit, r2) r4 = PyObject_IsTrue(r3) r5 = r4 >= 0 :: signed if not r5 goto L5 (error at f:2) else goto L1 :: bool L1: r6 = truncate r4: i32 to builtins.bool if not r6 goto L2 else goto L3 :: bool L2: r7 = 0 goto L4 L3: r7 = 1 L4: return r7 L5: r8 = <error> :: bool return r8 ``` IR after: ``` def f(x, y): x, y :: tuple[float] r0, r1 :: float r2 :: bit r3 :: bool L0: r0 = x[0] r1 = y[0] r2 = r0 == r1 if not r2 goto L1 else goto L2 :: bool L1: r3 = 0 goto L3 L2: r3 = 1 L3: return r3 ``` Tested using the following benchmark: ``` def f(x: tuple[float,float], y: tuple[float,float]) -> bool: return x == y def bench(n: int) -> None: for x in range(n): lhs = (float(x), float(x * 2)) rhs = (float(x), float(x * 3)) f(lhs, rhs) from time import time bench(1000) t0 = time() bench(50 * 1000 * 1000) print(time() - t0) ``` Execution time goes from ~315ms to ~150ms on my machine.
1 parent afd5a38 commit f9fe331

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

mypyc/irbuild/ll_builder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1534,7 +1534,7 @@ def compare_tuples(self, lhs: Value, rhs: Value, op: str, line: int = -1) -> Val
15341534
compare = self.binary_op(lhs_item, rhs_item, op, line)
15351535
# Cast to bool if necessary since most types uses comparison returning a object type
15361536
# See generic_ops.py for more information
1537-
if not is_bool_rprimitive(compare.type):
1537+
if not (is_bool_rprimitive(compare.type) or is_bit_rprimitive(compare.type)):
15381538
compare = self.primitive_op(bool_op, [compare], line)
15391539
if i < len(lhs.type.types) - 1:
15401540
branch = Branch(compare, early_stop, check_blocks[i + 1], Branch.BOOL)

mypyc/test-data/irbuild-tuple.test

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,3 +453,26 @@ L0:
453453
r0 = CPySequence_Multiply(a, 4)
454454
b = r0
455455
return 1
456+
457+
[case testTupleFloatElementComparison]
458+
def f(x: tuple[float], y: tuple[float]) -> bool:
459+
return x == y
460+
461+
[out]
462+
def f(x, y):
463+
x, y :: tuple[float]
464+
r0, r1 :: float
465+
r2 :: bit
466+
r3 :: bool
467+
L0:
468+
r0 = x[0]
469+
r1 = y[0]
470+
r2 = r0 == r1
471+
if not r2 goto L1 else goto L2 :: bool
472+
L1:
473+
r3 = 0
474+
goto L3
475+
L2:
476+
r3 = 1
477+
L3:
478+
return r3

0 commit comments

Comments
 (0)