Skip to content

Commit d35e571

Browse files
authored
Optimize type parameter checks in subtype checking (#14324)
Avoid the use of a nested function, which are a bit slow when compiled with mypyc. Also avoid a callable value and instead call a function directly, which allows using faster native calls. Based on a quick experiment, this speeds up self check by about 3%. This addresses some of the slowdown introduced in #13303.
1 parent c588852 commit d35e571

File tree

1 file changed

+28
-32
lines changed

1 file changed

+28
-32
lines changed

mypy/subtypes.py

+28-32
Original file line numberDiff line numberDiff line change
@@ -330,34 +330,28 @@ def check_item(left: Type, right: Type, subtype_context: SubtypeContext) -> bool
330330

331331

332332
def check_type_parameter(
333-
lefta: Type, righta: Type, variance: int, proper_subtype: bool, subtype_context: SubtypeContext
333+
left: Type, right: Type, variance: int, proper_subtype: bool, subtype_context: SubtypeContext
334334
) -> bool:
335-
def check(left: Type, right: Type) -> bool:
336-
return (
337-
is_proper_subtype(left, right, subtype_context=subtype_context)
338-
if proper_subtype
339-
else is_subtype(left, right, subtype_context=subtype_context)
340-
)
341-
342335
if variance == COVARIANT:
343-
return check(lefta, righta)
336+
if proper_subtype:
337+
return is_proper_subtype(left, right, subtype_context=subtype_context)
338+
else:
339+
return is_subtype(left, right, subtype_context=subtype_context)
344340
elif variance == CONTRAVARIANT:
345-
return check(righta, lefta)
341+
if proper_subtype:
342+
return is_proper_subtype(right, left, subtype_context=subtype_context)
343+
else:
344+
return is_subtype(right, left, subtype_context=subtype_context)
346345
else:
347346
if proper_subtype:
348347
# We pass ignore_promotions=False because it is a default for subtype checks.
349348
# The actual value will be taken from the subtype_context, and it is whatever
350349
# the original caller passed.
351350
return is_same_type(
352-
lefta, righta, ignore_promotions=False, subtype_context=subtype_context
351+
left, right, ignore_promotions=False, subtype_context=subtype_context
353352
)
354-
return is_equivalent(lefta, righta, subtype_context=subtype_context)
355-
356-
357-
def ignore_type_parameter(
358-
lefta: Type, righta: Type, variance: int, proper_subtype: bool, subtype_context: SubtypeContext
359-
) -> bool:
360-
return True
353+
else:
354+
return is_equivalent(left, right, subtype_context=subtype_context)
361355

362356

363357
class SubtypeVisitor(TypeVisitor[bool]):
@@ -366,9 +360,6 @@ def __init__(self, right: Type, subtype_context: SubtypeContext, proper_subtype:
366360
self.orig_right = right
367361
self.proper_subtype = proper_subtype
368362
self.subtype_context = subtype_context
369-
self.check_type_parameter = (
370-
ignore_type_parameter if subtype_context.ignore_type_params else check_type_parameter
371-
)
372363
self.options = subtype_context.options
373364
self._subtype_kind = SubtypeVisitor.build_subtype_kind(subtype_context, proper_subtype)
374365

@@ -572,17 +563,22 @@ def check_mixed(
572563
)
573564
else:
574565
type_params = zip(t.args, right.args, right.type.defn.type_vars)
575-
for lefta, righta, tvar in type_params:
576-
if isinstance(tvar, TypeVarType):
577-
if not self.check_type_parameter(
578-
lefta, righta, tvar.variance, self.proper_subtype, self.subtype_context
579-
):
580-
nominal = False
581-
else:
582-
if not self.check_type_parameter(
583-
lefta, righta, COVARIANT, self.proper_subtype, self.subtype_context
584-
):
585-
nominal = False
566+
if not self.subtype_context.ignore_type_params:
567+
for lefta, righta, tvar in type_params:
568+
if isinstance(tvar, TypeVarType):
569+
if not check_type_parameter(
570+
lefta,
571+
righta,
572+
tvar.variance,
573+
self.proper_subtype,
574+
self.subtype_context,
575+
):
576+
nominal = False
577+
else:
578+
if not check_type_parameter(
579+
lefta, righta, COVARIANT, self.proper_subtype, self.subtype_context
580+
):
581+
nominal = False
586582
if nominal:
587583
TypeState.record_subtype_cache_entry(self._subtype_kind, left, right)
588584
return nominal

0 commit comments

Comments
 (0)