From 9a2c62568a5cda98a0eae4c369c5eed131d7fb25 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Sat, 7 Dec 2024 18:45:53 +0000 Subject: [PATCH] Use more aggressive gc thresholds, and tune earlier In some cases gc was consuming a significant fraction of CPU, so run gc less often. Also tune gc very early, to run gc less during import time -- not sure if this has any significant impact, but in an unrelated project this was somewhat helpful. This makes incremental checking of torch 27% faster (based on 100 measurements), and also speeds up self check by about 10% (both incremental and non-incremental). --- mypy/__main__.py | 5 +++++ mypy/build.py | 9 ++++----- mypy/gctune.py | 15 +++++++++++++++ mypyc/__main__.py | 5 +++++ 4 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 mypy/gctune.py diff --git a/mypy/__main__.py b/mypy/__main__.py index 049553cd1b44..fea69b9cfd35 100644 --- a/mypy/__main__.py +++ b/mypy/__main__.py @@ -2,6 +2,11 @@ from __future__ import annotations +from mypy.gctune import tune_gc + +# Tune GC as early as possible, before most imports +tune_gc() + import os import sys import traceback diff --git a/mypy/build.py b/mypy/build.py index 40dd73313335..8b5027a45550 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -16,10 +16,8 @@ import collections import contextlib import errno -import gc import json import os -import platform import re import stat import sys @@ -46,6 +44,7 @@ from mypy.checker import TypeChecker from mypy.error_formatter import OUTPUT_CHOICES, ErrorFormatter from mypy.errors import CompileError, ErrorInfo, Errors, report_internal_error +from mypy.gctune import tune_gc from mypy.graph_utils import prepare_sccs, strongly_connected_components, topsort from mypy.indirection import TypeIndirectionVisitor from mypy.messages import MessageBuilder @@ -217,9 +216,9 @@ def _build( stderr: TextIO, extra_plugins: Sequence[Plugin], ) -> BuildResult: - if platform.python_implementation() == "CPython": - # This seems the most reasonable place to tune garbage collection. - gc.set_threshold(150 * 1000) + # We tune gc in __main__, but also do it here in case we are called from + # another entry point such as a test. + tune_gc() data_dir = default_data_dir() fscache = fscache or FileSystemCache() diff --git a/mypy/gctune.py b/mypy/gctune.py new file mode 100644 index 000000000000..ceaff7f9c2d3 --- /dev/null +++ b/mypy/gctune.py @@ -0,0 +1,15 @@ +"""Tuning cyclic garbage collector (GC) parameters for better performance. + +Since this is called very early, before most imports, don't add new import +dependencies! +""" + +import gc +import platform + + +def tune_gc() -> None: + if platform.python_implementation() == "CPython": + # Run gc less frequently, as otherwise we can spent a large fraction of + # cpu in gc. + gc.set_threshold(200 * 1000, 30, 30) diff --git a/mypyc/__main__.py b/mypyc/__main__.py index 653199e0fb55..0ea0f6fb8a20 100644 --- a/mypyc/__main__.py +++ b/mypyc/__main__.py @@ -12,6 +12,11 @@ from __future__ import annotations +from mypy.gctune import tune_gc + +# Tune GC as early as possible, before most imports +tune_gc() + import os import os.path import subprocess