-
-
Notifications
You must be signed in to change notification settings - Fork 33.6k
gh-92810: Reduce memory usage by ABCMeta.__subclasscheck__ #131914
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
3 similar comments
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
Signed-off-by: Martynov Maxim <martinov_m_s_@mail.ru>
Signed-off-by: Martynov Maxim <martinov_m_s_@mail.ru>
Signed-off-by: Martynov Maxim <martinov_m_s_@mail.ru>
Signed-off-by: Martynov Maxim <martinov_m_s_@mail.ru>
Signed-off-by: Martynov Maxim <martinov_m_s_@mail.ru>
abf4bfe to
b7603e0
Compare
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Yes, please add both benchmarks. |
|
Added scripts and microbenchmark results to PR description |
|
The numbers seem good but I'm a bit worried about the cached vs non-cached class. Or specifically, I'm worried about the regular The memory improvements are definitely important. But I really wonder whether the performance impact outweigh the memory improvements. I don't deny that they are good but making it slower is something that could be annoying as well. As such, I'd like the opinion of other core devs such as @JelleZijlstra @sobolevn @serhiy-storchaka @encukou |
Me too. I'm not sure why Maybe someone could run the same benchmark on other environment to get some numbers to compare. I haven't tested free-threading build, for example. |
This comment was marked as outdated.
This comment was marked as outdated.
|
pyperformance results: Benchmarks with tag 'apps':
Benchmark hidden because not significant (2): 2to3, sphinx Benchmarks with tag 'asyncio':
Benchmark hidden because not significant (11): async_tree_io, async_tree_none, async_tree_eager_memoization, async_tree_eager_io_tg, asyncio_websockets, async_tree_eager_io, async_tree_eager_cpu_io_mixed, coroutines, asyncio_tcp, async_tree_io_tg, async_tree_memoization Benchmarks with tag 'math':
Benchmarks with tag 'regex':
Benchmarks with tag 'serialize':
Benchmark hidden because not significant (5): pickle_pure_python, pickle_list, xml_etree_iterparse, pickle, json_loads Benchmarks with tag 'startup':
Benchmarks with tag 'template':
Benchmark hidden because not significant (2): genshi_text, genshi_xml All benchmarks:
Benchmark hidden because not significant (41): async_tree_io, async_tree_none, deepcopy_reduce, scimark_lu, coverage, pickle_pure_python, 2to3, async_tree_eager_memoization, deepcopy, genshi_text, pickle_list, sqlite_synth, async_tree_eager_io_tg, k_core, many_optionals, xml_etree_iterparse, pickle, asyncio_websockets, sqlalchemy_imperative, logging_format, deepcopy_memo, scimark_sor, xdsl_constant_fold, sqlglot_v2_optimize, create_gc_cycles, async_tree_eager_io, json_loads, async_tree_eager_cpu_io_mixed, sqlglot_v2_transpile, sqlglot_v2_parse, coroutines, crypto_pyaes, sphinx, asyncio_tcp, hexiom, dask, async_tree_io_tg, genshi_xml, connected_components, telco, async_tree_memoization |
|
I've updated microbenchmark script and results in the PR description: #131914 (comment). Previous microbenchmark implementation created global large class tree, and tested different According to these results, and to pyperformance run on my machine, timing is not that different comparing to |
_abc._abc_subclasscheckhas very poor performance and (I think) a memory leak #92810For python build using
--enable-optimizations:benchmark.py
isinstance(child, Parent)2MiB...15MiB
3MiB...15MiB
10MiB...23MiB
10MiB...23MiB
issubclass(Child, Parent)0MiB
0MiB
6MiB...8MiB
5MiB...8MiB
isinstance(child, Grandparent)0MiB...2MiB
0MiB...2MiB
4MiB...6MiB
3MiB...6MiB
issubclass(Child, Grandparent)0MiB
0MiB
0MiB...2MiB
0MiB...1MiB
not isinstance(child, Sibling)2MiB...14MiB
1MiB...14MiB
14MiB...23MiB
13MiB...22MiB
not issubclass(Child, Sibling)0MiB
0MiB
10MiB...12MiB
7MiB...10MiB
not isinstance(child, Cousin)1MiB...2MiB
0MiB
8MiB...10MiB
6MiB...8MiB
not issubclass(Child, Cousin)0MiB
0MiB
5MiB...6MiB
2MiB...3MiB
not isinstance(child, Uncle)5705MiB...6332MiB
0MiB
3797MiB...4423MiB
5MiB
not issubclass(Child, Uncle)5704MiB
0MiB
3794MiB...3795MiB
3MiB
Memory increment is measured during
isinstance()/issubclass()calls, not during preparation, like class creation or registration.isinstance(child, Parent.register)0MiB
0MiB
0MiB
0MiB
issubclass(Child, Parent.register)0MiB
0MiB
0MiB
0MiB
isinstance(child, Grandparent.register)0MiB
0MiB
0MiB
0MiB
issubclass(Child, Grandparent.register)0MiB
0MiB
0MiB
0MiB
not isinstance(child, Sibling.register)0MiB
0MiB...2MiB
0MiB
2MiB
not issubclass(Child, Sibling.register)0MiB
1MiB
0MiB
2MiB
not isinstance(child, Cousin.register)0MiB
2MiB
0MiB
3MiB
not issubclass(Child, Cousin.register)0MiB
2MiB
0MiB
3MiB
not isinstance(child, Uncle.register)0MiB
2MiB...3MiB
0MiB
4MiB
not issubclass(Child, Uncle.register)0MiB
2MiB
0MiB
4MiB
isinstance(child, Parent.__subclasses__)0MiB
0MiB
0MiB
0MiB
issubclass(Child, Parent.__subclasses__)0MiB
0MiB
0MiB
0MiB
isinstance(child, Grandparent.__subclasses__)0MiB
0MiB
0MiB
0MiB
issubclass(Child, Grandparent.__subclasses__)0MiB
0MiB
0MiB
0MiB
not isinstance(child, Sibling.__subclasses__)0MiB
0MiB
0MiB
1MiB
not issubclass(Child, Sibling.__subclasses__)0MiB
0MiB
0MiB
1MiB
not isinstance(child, Cousin.__subclasses__)0MiB
0MiB
0MiB
1MiB
not issubclass(Child, Cousin.__subclasses__)0MiB
0MiB
0MiB
1MiB
not isinstance(child, Uncle.__subclasses__)0MiB
0MiB
0MiB
2MiB
not issubclass(Child, Uncle.__subclasses__)0MiB
0MiB
0MiB
2MiB