Skip to content

Commit 378119f

Browse files
authored
[mypyc] Ignore super calls to object.__init__() (#11938)
This speeds up the deltablue benchmark by 15%.
1 parent 531a1f0 commit 378119f

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

mypyc/irbuild/expression.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,11 +326,20 @@ def translate_super_method_call(builder: IRBuilder, expr: CallExpr, callee: Supe
326326
return translate_call(builder, expr, callee)
327327

328328
ir = builder.mapper.type_to_ir[callee.info]
329-
# Search for the method in the mro, skipping ourselves.
329+
# Search for the method in the mro, skipping ourselves. We
330+
# determine targets of super calls to native methods statically.
330331
for base in ir.mro[1:]:
331332
if callee.name in base.method_decls:
332333
break
333334
else:
335+
if (ir.is_ext_class
336+
and ir.builtin_base is None
337+
and not ir.inherits_python
338+
and callee.name == '__init__'
339+
and len(expr.args) == 0):
340+
# Call translates to object.__init__(self), which is a
341+
# no-op, so omit the call.
342+
return builder.none()
334343
return translate_call(builder, expr, callee)
335344

336345
decl = base.method_decl(callee.name)

mypyc/test-data/irbuild-classes.test

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,53 @@ L0:
795795
r0 = T.foo(self)
796796
return 1
797797

798+
[case testSuperCallToObjectInitIsOmitted]
799+
class C:
800+
def __init__(self) -> None:
801+
super().__init__()
802+
class D: pass
803+
class E(D):
804+
def __init__(self) -> None:
805+
super().__init__()
806+
class F(C):
807+
def __init__(self) -> None:
808+
super().__init__()
809+
class DictSubclass(dict):
810+
def __init__(self) -> None:
811+
super().__init__()
812+
[out]
813+
def C.__init__(self):
814+
self :: __main__.C
815+
L0:
816+
return 1
817+
def E.__init__(self):
818+
self :: __main__.E
819+
L0:
820+
return 1
821+
def F.__init__(self):
822+
self :: __main__.F
823+
r0 :: None
824+
L0:
825+
r0 = C.__init__(self)
826+
return 1
827+
def DictSubclass.__init__(self):
828+
self :: dict
829+
r0 :: object
830+
r1 :: str
831+
r2, r3, r4 :: object
832+
r5 :: str
833+
r6, r7 :: object
834+
L0:
835+
r0 = builtins :: module
836+
r1 = 'super'
837+
r2 = CPyObject_GetAttr(r0, r1)
838+
r3 = __main__.DictSubclass :: type
839+
r4 = PyObject_CallFunctionObjArgs(r2, r3, self, 0)
840+
r5 = '__init__'
841+
r6 = CPyObject_GetAttr(r4, r5)
842+
r7 = PyObject_CallFunctionObjArgs(r6, 0)
843+
return 1
844+
798845
[case testClassVariable]
799846
from typing import ClassVar
800847
class A:

0 commit comments

Comments
 (0)