|
116 | 116 | "abc",
|
117 | 117 | }
|
118 | 118 |
|
| 119 | +# We are careful now, we can increase this in future if safe/useful. |
| 120 | +MAX_GC_FREEZE_CYCLES = 1 |
119 | 121 |
|
120 | 122 | Graph: _TypeAlias = dict[str, "State"]
|
121 | 123 |
|
@@ -707,6 +709,8 @@ def __init__(
|
707 | 709 | # new file can be processed O(n**2) times. This cache
|
708 | 710 | # avoids most of this redundant work.
|
709 | 711 | self.ast_cache: dict[str, tuple[MypyFile, list[ErrorInfo]]] = {}
|
| 712 | + # Number of times we used GC optimization hack for fresh SCCs. |
| 713 | + self.gc_freeze_cycles = 0 |
710 | 714 |
|
711 | 715 | def dump_stats(self) -> None:
|
712 | 716 | if self.options.dump_build_stats:
|
@@ -3326,8 +3330,29 @@ def process_graph(graph: Graph, manager: BuildManager) -> None:
|
3326 | 3330 | #
|
3327 | 3331 | # TODO: see if it's possible to determine if we need to process only a
|
3328 | 3332 | # _subset_ of the past SCCs instead of having to process them all.
|
| 3333 | + if ( |
| 3334 | + platform.python_implementation() == "CPython" |
| 3335 | + and manager.gc_freeze_cycles < MAX_GC_FREEZE_CYCLES |
| 3336 | + ): |
| 3337 | + # When deserializing cache we create huge amount of new objects, so even |
| 3338 | + # with our generous GC thresholds, GC is still doing a lot of pointless |
| 3339 | + # work searching for garbage. So, we temporarily disable it when |
| 3340 | + # processing fresh SCCs, and then move all the new objects to the oldest |
| 3341 | + # generation with the freeze()/unfreeze() trick below. This is arguably |
| 3342 | + # a hack, but it gives huge performance wins for large third-party |
| 3343 | + # libraries, like torch. |
| 3344 | + gc.collect() |
| 3345 | + gc.disable() |
3329 | 3346 | for prev_scc in fresh_scc_queue:
|
3330 | 3347 | process_fresh_modules(graph, prev_scc, manager)
|
| 3348 | + if ( |
| 3349 | + platform.python_implementation() == "CPython" |
| 3350 | + and manager.gc_freeze_cycles < MAX_GC_FREEZE_CYCLES |
| 3351 | + ): |
| 3352 | + manager.gc_freeze_cycles += 1 |
| 3353 | + gc.freeze() |
| 3354 | + gc.unfreeze() |
| 3355 | + gc.enable() |
3331 | 3356 | fresh_scc_queue = []
|
3332 | 3357 | size = len(scc)
|
3333 | 3358 | if size == 1:
|
|
0 commit comments