Skip to content

Conversation

sergey-miryanov
Copy link
Contributor

@sergey-miryanov sergey-miryanov commented Apr 6, 2025

Removes resolve_slotdups.

@python-cla-bot
Copy link

python-cla-bot bot commented Apr 6, 2025

All commit authors signed the Contributor License Agreement.

CLA signed

@StanFromIreland
Copy link
Member

Maybe take a look at this comment and have it in mind.

@sergey-miryanov
Copy link
Contributor Author

@StanFromIreland Yeah, thanks! I just checked both scripts - and timing closely same. But I not finished main task, so results can changed.

@AA-Turner AA-Turner added the interpreter-core (Objects, Python, Grammar, and Parser dirs) label Apr 7, 2025
@sergey-miryanov
Copy link
Contributor Author

sergey-miryanov commented Apr 9, 2025

Intermediate results:

Benchmark results (outdated)
Running Release|x64 interpreter...
Python 3.14.0a6+ (heads/gh-132042-optimize-class-creation:b0ad8754b45, Apr  9 2025, 11:38:25) [MSC v.1943 64 bit (AMD64)]

+----------------------------------------------------------------------------+---------+-----------------------+
| Benchmark                                                                  | ref     | new                   |
+============================================================================+=========+=======================+
| empty_cls-1000                                                             | 4.32 ms | 3.50 ms: 1.24x faster |
+----------------------------------------------------------------------------+---------+-----------------------+
| cls_with_dunders-1000                                                      | 5.03 ms | 4.32 ms: 1.16x faster |
+----------------------------------------------------------------------------+---------+-----------------------+
| empty_cls_with_bases-1000-A, B                                             | 5.62 ms | 3.89 ms: 1.45x faster |
+----------------------------------------------------------------------------+---------+-----------------------+
| cls_with_bases-1000-A, B                                                   | 6.18 ms | 4.62 ms: 1.34x faster |
+----------------------------------------------------------------------------+---------+-----------------------+
| empty_cls_with_bases-1000-A, B, D                                          | 6.37 ms | 4.18 ms: 1.52x faster |
+----------------------------------------------------------------------------+---------+-----------------------+
| cls_with_bases-1000-A, B, D                                                | 6.81 ms | 4.92 ms: 1.39x faster |
+----------------------------------------------------------------------------+---------+-----------------------+
| empty_cls_with_bases-1000-A_with_dunders, B_with_dunders                   | 5.40 ms | 3.89 ms: 1.39x faster |
+----------------------------------------------------------------------------+---------+-----------------------+
| cls_with_bases-1000-A_with_dunders, B_with_dunders                         | 6.08 ms | 4.66 ms: 1.31x faster |
+----------------------------------------------------------------------------+---------+-----------------------+
| empty_cls_with_bases-1000-A_with_dunders, B_with_dunders, D_with_dunders   | 6.08 ms | 4.24 ms: 1.44x faster |
+----------------------------------------------------------------------------+---------+-----------------------+
| cls_with_bases-1000-A_with_dunders, B_with_dunders, D_with_dunders         | 6.79 ms | 5.01 ms: 1.36x faster |
+----------------------------------------------------------------------------+---------+-----------------------+
| empty_cls-100000                                                           | 436 ms  | 356 ms: 1.23x faster  |
+----------------------------------------------------------------------------+---------+-----------------------+
| cls_with_dunders-100000                                                    | 500 ms  | 434 ms: 1.15x faster  |
+----------------------------------------------------------------------------+---------+-----------------------+
| empty_cls_with_bases-100000-A, B                                           | 563 ms  | 387 ms: 1.46x faster  |
+----------------------------------------------------------------------------+---------+-----------------------+
| cls_with_bases-100000-A, B                                                 | 612 ms  | 463 ms: 1.32x faster  |
+----------------------------------------------------------------------------+---------+-----------------------+
| empty_cls_with_bases-100000-A, B, D                                        | 631 ms  | 418 ms: 1.51x faster  |
+----------------------------------------------------------------------------+---------+-----------------------+
| cls_with_bases-100000-A, B, D                                              | 683 ms  | 493 ms: 1.39x faster  |
+----------------------------------------------------------------------------+---------+-----------------------+
| empty_cls_with_bases-100000-A_with_dunders, B_with_dunders                 | 545 ms  | 389 ms: 1.40x faster  |
+----------------------------------------------------------------------------+---------+-----------------------+
| cls_with_bases-100000-A_with_dunders, B_with_dunders                       | 607 ms  | 467 ms: 1.30x faster  |
+----------------------------------------------------------------------------+---------+-----------------------+
| empty_cls_with_bases-100000-A_with_dunders, B_with_dunders, D_with_dunders | 609 ms  | 423 ms: 1.44x faster  |
+----------------------------------------------------------------------------+---------+-----------------------+
| cls_with_bases-100000-A_with_dunders, B_with_dunders, D_with_dunders       | 679 ms  | 502 ms: 1.35x faster  |
+----------------------------------------------------------------------------+---------+-----------------------+
| Geometric mean                                                             | (ref)   | 1.35x faster          |
+----------------------------------------------------------------------------+---------+-----------------------+

b.txt

@sergey-miryanov
Copy link
Contributor Author

sergey-miryanov commented Apr 9, 2025

I added tests from gh-76527 (script for testing with pyperf b.txt):

  • empty_cls - tests for classes without any methods
  • cls - tests for classes with few dunder methods
  • bases - with suffix _dun - base classes with few dunder methods
Benchmark results (outdated)
+---------------------------------------------------------------+----------+-----------------------+
| Benchmark                                                     | ref      | new                   |
+===============================================================+==========+=======================+
| 1000-empty_cls                                                | 4.42 ms  | 3.50 ms: 1.26x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_dunders                                         | 5.25 ms  | 4.45 ms: 1.18x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A', 'B']                    | 5.70 ms  | 3.84 ms: 1.48x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_bases-bases=['A', 'B']                          | 6.26 ms  | 4.62 ms: 1.35x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A', 'B', 'D']               | 6.49 ms  | 4.16 ms: 1.56x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_bases-bases=['A', 'B', 'D']                     | 6.97 ms  | 4.94 ms: 1.41x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun']            | 5.52 ms  | 3.89 ms: 1.42x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_bases-bases=['A_dun', 'B_dun']                  | 6.21 ms  | 4.67 ms: 1.33x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun']   | 6.20 ms  | 4.20 ms: 1.47x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun']         | 7.10 ms  | 5.02 ms: 1.42x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-empty_cls_with_bases-bases=['Logger']                    | 5.42 ms  | 4.22 ms: 1.28x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_bases-bases=['Logger']                          | 6.05 ms  | 5.08 ms: 1.19x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-empty_cls_with_bases-bases=['DatagramHandler']           | 6.63 ms  | 4.42 ms: 1.50x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_bases-bases=['DatagramHandler']                 | 7.23 ms  | 5.24 ms: 1.38x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-empty_cls_with_bases-bases=['MagicMock']                 | 7.66 ms  | 4.95 ms: 1.55x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_bases-bases=['MagicMock']                       | 8.26 ms  | 5.74 ms: 1.44x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-empty_cls_with_bases-bases=['Shelf']                     | 9.46 ms  | 6.86 ms: 1.38x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_bases-bases=['Shelf']                           | 10.2 ms  | 7.84 ms: 1.30x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-empty_cls_with_bases-bases=['tuple']                     | 5.62 ms  | 4.18 ms: 1.35x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_bases-bases=['tuple']                           | 6.33 ms  | 5.53 ms: 1.14x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-empty_cls_with_bases-bases=['dict']                      | 5.60 ms  | 4.90 ms: 1.14x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_bases-bases=['dict']                            | 6.30 ms  | 5.56 ms: 1.13x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-empty_cls_with_bases-bases=['list']                      | 5.99 ms  | 4.74 ms: 1.26x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 1000-cls_with_bases-bases=['list']                            | 6.68 ms  | 5.64 ms: 1.19x faster |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls                                              | 447 ms   | 354 ms: 1.26x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_dunders                                       | 510 ms   | 436 ms: 1.17x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls_with_bases-bases=['A', 'B']                  | 569 ms   | 392 ms: 1.45x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_bases-bases=['A', 'B']                        | 631 ms   | 470 ms: 1.34x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls_with_bases-bases=['A', 'B', 'D']             | 644 ms   | 416 ms: 1.55x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_bases-bases=['A', 'B', 'D']                   | 702 ms   | 499 ms: 1.41x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls_with_bases-bases=['A_dun', 'B_dun']          | 550 ms   | 387 ms: 1.42x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_bases-bases=['A_dun', 'B_dun']                | 627 ms   | 474 ms: 1.32x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun'] | 621 ms   | 422 ms: 1.47x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun']       | 694 ms   | 509 ms: 1.36x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls_with_bases-bases=['Logger']                  | 540 ms   | 418 ms: 1.29x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_bases-bases=['Logger']                        | 612 ms   | 508 ms: 1.20x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls_with_bases-bases=['DatagramHandler']         | 657 ms   | 441 ms: 1.49x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_bases-bases=['DatagramHandler']               | 726 ms   | 530 ms: 1.37x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls_with_bases-bases=['MagicMock']               | 764 ms   | 492 ms: 1.55x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_bases-bases=['MagicMock']                     | 828 ms   | 580 ms: 1.43x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls_with_bases-bases=['Shelf']                   | 954 ms   | 689 ms: 1.39x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_bases-bases=['Shelf']                         | 1.04 sec | 784 ms: 1.33x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls_with_bases-bases=['tuple']                   | 558 ms   | 417 ms: 1.34x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_bases-bases=['tuple']                         | 649 ms   | 502 ms: 1.29x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls_with_bases-bases=['dict']                    | 579 ms   | 464 ms: 1.25x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_bases-bases=['dict']                          | 648 ms   | 547 ms: 1.19x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-empty_cls_with_bases-bases=['list']                    | 630 ms   | 476 ms: 1.32x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| 100000-cls_with_bases-bases=['list']                          | 686 ms   | 563 ms: 1.22x faster  |
+---------------------------------------------------------------+----------+-----------------------+
| Geometric mean                                                | (ref)    | 1.34x faster          |
+---------------------------------------------------------------+----------+-----------------------+

Also benchgcclasses2.py output:
ref:

➜ .\python.bat ..\cpython-issues\gh-132042-optimize-class-creation\benchgcclasses2.py
Running Release|x64 interpreter...
GC time: 93.8 ms
gc: collecting generation 2...
gc: objects in each generation: 0 0 905261
gc: objects in permanent generation: 0

➜ .\python.bat ..\cpython-issues\gh-132042-optimize-class-creation\benchgcclasses2.py
Running Release|x64 interpreter...
GC time: 125.0 ms
gc: collecting generation 2...
gc: objects in each generation: 0 0 905261
gc: objects in permanent generation: 0
RSS:

new:

➜ .\python.bat ..\cpython-issues\gh-132042-optimize-class-creation\benchgcclasses2.py
Running Release|x64 interpreter...
GC time: 109.4 ms
gc: collecting generation 2...
gc: objects in each generation: 0 0 905262
gc: objects in permanent generation: 0
RSS:

➜ .\python.bat ..\cpython-issues\gh-132042-optimize-class-creation\benchgcclasses2.py
Running Release|x64 interpreter...
GC time: 125.0 ms
gc: collecting generation 2...
gc: objects in each generation: 0 0 905262
gc: objects in permanent generation: 0
RSS:

Time varies, I'm not sure it is statistically significant. Count of objects closely the same.

Async import time (➜ .\python.bat -X importtime -c 'import asyncio'):
ref:

import time:      1116 |      86283 | asyncio

new:

import time:      1014 |      82194 | asyncio

@sergey-miryanov
Copy link
Contributor Author

sergey-miryanov commented Apr 9, 2025

Remove resolve_slotdups (new2):

Benchmark results (outdated)
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| Benchmark                                                   | ref     | new                   | new2                  |
+=============================================================+=========+=======================+=======================+
| 1000-empty_cls                                              | 4.42 ms | 3.50 ms: 1.26x faster | 3.37 ms: 1.31x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_dunders                                       | 5.25 ms | 4.45 ms: 1.18x faster | 4.38 ms: 1.20x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A', 'B']                  | 5.70 ms | 3.84 ms: 1.48x faster | 3.68 ms: 1.55x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_bases-bases=['A', 'B']                        | 6.26 ms | 4.62 ms: 1.35x faster | 4.51 ms: 1.39x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A', 'B', 'D']             | 6.49 ms | 4.16 ms: 1.56x faster | 4.00 ms: 1.62x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_bases-bases=['A', 'B', 'D']                   | 6.97 ms | 4.94 ms: 1.41x faster | 4.80 ms: 1.45x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun']          | 5.52 ms | 3.89 ms: 1.42x faster | 3.74 ms: 1.48x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_bases-bases=['A_dun', 'B_dun']                | 6.21 ms | 4.67 ms: 1.33x faster | 4.55 ms: 1.36x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun'] | 6.20 ms | 4.20 ms: 1.47x faster | 4.08 ms: 1.52x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun']       | 7.10 ms | 5.02 ms: 1.42x faster | 4.89 ms: 1.45x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-empty_cls_with_bases-bases=['Logger']                  | 5.42 ms | 4.22 ms: 1.28x faster | 4.06 ms: 1.33x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_bases-bases=['Logger']                        | 6.05 ms | 5.08 ms: 1.19x faster | 4.97 ms: 1.22x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-empty_cls_with_bases-bases=['DatagramHandler']         | 6.63 ms | 4.42 ms: 1.50x faster | 4.26 ms: 1.56x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_bases-bases=['DatagramHandler']               | 7.23 ms | 5.24 ms: 1.38x faster | 5.09 ms: 1.42x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-empty_cls_with_bases-bases=['MagicMock']               | 7.66 ms | 4.95 ms: 1.55x faster | 4.83 ms: 1.59x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_bases-bases=['MagicMock']                     | 8.26 ms | 5.74 ms: 1.44x faster | 5.64 ms: 1.46x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-empty_cls_with_bases-bases=['Shelf']                   | 9.46 ms | 6.86 ms: 1.38x faster | 6.67 ms: 1.42x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_bases-bases=['Shelf']                         | 10.2 ms | 7.84 ms: 1.30x faster | 7.62 ms: 1.34x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-empty_cls_with_bases-bases=['tuple']                   | 5.62 ms | 4.18 ms: 1.35x faster | 3.82 ms: 1.47x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_bases-bases=['tuple']                         | 6.33 ms | 5.53 ms: 1.14x faster | 4.57 ms: 1.39x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-empty_cls_with_bases-bases=['dict']                    | 5.60 ms | 4.90 ms: 1.14x faster | 4.32 ms: 1.30x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_bases-bases=['dict']                          | 6.30 ms | 5.56 ms: 1.13x faster | 5.15 ms: 1.22x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-empty_cls_with_bases-bases=['list']                    | 5.99 ms | 4.74 ms: 1.26x faster | 4.39 ms: 1.36x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| 1000-cls_with_bases-bases=['list']                          | 6.68 ms | 5.64 ms: 1.19x faster | 5.18 ms: 1.29x faster |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+
| Geometric mean                                              | (ref)   | 1.34x faster          | 1.40x faster          |
+-------------------------------------------------------------+---------+-----------------------+-----------------------+

@sergey-miryanov sergey-miryanov marked this pull request as ready for review April 9, 2025 20:54
@sergey-miryanov
Copy link
Contributor Author

It is ready to review. Please take a look.

Co-authored-by: Victor Stinner <vstinner@python.org>
@sergey-miryanov
Copy link
Contributor Author

The following tests call update_one_slot (via fixup_slot_dispatchers or update_slot) and may be affected by this PR.

test warmup calls x slotdefs count loop calls x slotdefs count result (base vs pr)
bench_mp_pool 27 0 1.01x faster (82.8 ms / 81.7 ms)
bench_thread_pool 25 0 1.01x slower (887 us / 891 us)
deepcopy_reduce 0 1 1.02x slower (2.73 us / 2.78 us)
docutils 347 0 not significant
dulwich_log 3 0 1.01x slower (59.7 ms / 60.1 ms)
genshi_text 9 0 1.00x slower (21.0 ms / 21.1 ms)
genshi_xml 9 0 1.01x slower (49.2 ms / 49.6 ms)
html5lib 33 0 1.04x slower (60.0 ms / 62.6 ms)
pprint_pformat 196 0 1.01x faster (1.50 sec / 1.49 sec)
pylint 883 7 not significant
regex_v8 4 0 1.05x faster (23.6 ms / 22.5 ms)
sympy_expand 33 0 not significant
sympy_integrate 39 0 not significant
sympy_sum 39 1 1.01x slower (149 ms / 150 ms)
sympy_str 30 0 1.00x slower (268 ms / 269 ms)
typing_runtime_protocols 187 0 1.01x slower (168 us / 169 us)
xml_etree_parse 6 0 1.04x faster (147 ms / 141 ms)
xml_etree_iterparse 26 20 not significant
xml_etree_generate 6 0 1.01x faster (86.9 ms / 85.9 ms)
xml_etree_process 6 0 not significant

As can be seen most of the calls come from warmup iteration and shouldn't be counted in the results. Only the following tests call update_one_slot from inside loop iterations. pylint and xml_etree_iterparse have more calls than the other two tests but have 'not significant' results.

IMHO this set of benchmarks is not suitable to show the differences made by this PR.

@sergey-miryanov
Copy link
Contributor Author

Fixed merge conflicts.

Updated results:

Geometric mean - 1.12x faster
+-------------------------------------------------------------+---------+-----------------------+
| Benchmark                                                   | ref     | dups                  |
+=============================================================+=========+=======================+
| 1000-empty_cls                                              | 4.35 ms | 3.80 ms: 1.15x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_dunders                                       | 5.05 ms | 4.55 ms: 1.11x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A', 'B']                  | 5.58 ms | 4.93 ms: 1.13x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A', 'B']                        | 6.15 ms | 5.71 ms: 1.08x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A', 'B', 'D']             | 6.34 ms | 5.67 ms: 1.12x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A', 'B', 'D']                   | 6.82 ms | 6.35 ms: 1.07x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun']          | 5.39 ms | 4.89 ms: 1.10x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A_dun', 'B_dun']                | 6.11 ms | 5.67 ms: 1.08x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun'] | 6.07 ms | 5.54 ms: 1.09x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun']       | 6.84 ms | 6.37 ms: 1.07x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['Logger']                  | 5.30 ms | 4.74 ms: 1.12x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['Logger']                        | 5.92 ms | 5.47 ms: 1.08x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['DatagramHandler']         | 6.40 ms | 6.06 ms: 1.06x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['DatagramHandler']               | 7.03 ms | 6.63 ms: 1.06x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['MagicMock']               | 7.33 ms | 6.99 ms: 1.05x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['MagicMock']                     | 7.96 ms | 7.72 ms: 1.03x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['Shelf']                   | 9.40 ms | 8.92 ms: 1.05x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['Shelf']                         | 9.94 ms | 9.70 ms: 1.02x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['tuple']                   | 5.56 ms | 4.31 ms: 1.29x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['tuple']                         | 6.23 ms | 5.26 ms: 1.18x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['dict']                    | 5.56 ms | 4.50 ms: 1.24x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['dict']                          | 6.18 ms | 5.29 ms: 1.17x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['list']                    | 5.99 ms | 4.45 ms: 1.34x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['list']                          | 6.54 ms | 5.28 ms: 1.24x faster |
+-------------------------------------------------------------+---------+-----------------------+
| Geometric mean                                              | (ref)   | 1.12x faster          |
+-------------------------------------------------------------+---------+-----------------------+

sergey-miryanov and others added 4 commits October 1, 2025 23:41
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
Co-authored-by: Victor Stinner <vstinner@python.org>
@sergey-miryanov
Copy link
Contributor Author

@kumaraditya303 @vstinner Thanks for review!

I will be able to run benchmarks after updates on this weekends (now on traveling laptop).

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. A few coding style suggestions.

sergey-miryanov and others added 2 commits October 2, 2025 23:36
Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
Copy link
Contributor

@kumaraditya303 kumaraditya303 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice improvement!

@sergey-miryanov
Copy link
Contributor Author

@kumaraditya303 thanks!

@vstinner
Copy link
Member

vstinner commented Oct 3, 2025

Micro-benchmark on creating on empty class:

python -m pyperf timeit 'class A: pass'

Result: Mean +- std dev: [ref] 9.92 us +- 0.09 us -> [change] 8.47 us +- 0.10 us: 1.17x faster.

@vstinner vstinner merged commit e6e376a into python:main Oct 3, 2025
45 checks passed
@vstinner
Copy link
Member

vstinner commented Oct 3, 2025

Merged. Thank you, that's a nice performance enhancement!

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot AMD64 Debian root 3.x (tier-1) has failed when building commit e6e376a.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/345/builds/12336) and take a look at the build logs.
  4. Check if the failure is related to this commit (e6e376a) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/345/builds/12336

Failed tests:

  • test.test_multiprocessing_forkserver.test_processes
  • test.test_multiprocessing_spawn.test_misc
  • test.test_multiprocessing_forkserver.test_misc

Failed subtests:

  • test_large_pool - test.test_multiprocessing_spawn.test_misc.MiscTestCase.test_large_pool
  • test_many_processes - test.test_multiprocessing_forkserver.test_processes.WithProcessesTestProcess.test_many_processes

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/process.py", line 320, in _bootstrap
    self.run()
    ~~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/_test_multiprocessing.py", line 523, in _sleep_some_event
    event.set()
    ~~~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/synchronize.py", line 344, in set
    with self._cond:
         ^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/synchronize.py", line 242, in __exit__
    return self._lock.__exit__(*args)
           ~~~~~~~~~~~~~~~~~~~^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/synchronize.py", line 100, in __exit__
    return self._semlock.__exit__(*args)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^
KeyboardInterrupt
k


Traceback (most recent call last):
  File "<string>", line 1, in <module>
    from multiprocessing.forkserver import main; main(9, 10, ['__main__', 'test.test_multiprocessing_forkserver'], **{'sys_path': ['/root/buildarea/3.x.angelico-debian-amd64/build', '/root/buildarea/3.x.angelico-debian-amd64/build/target/lib/python315.zip', '/root/buildarea/3.x.angelico-debian-amd64/build/Lib', '/root/buildarea/3.x.angelico-debian-amd64/build/build/lib.linux-x86_64-3.15', '/root/.local/lib/python3.15/site-packages'], 'authkey_r': 12})
                                                 ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 329, in main
    pid = os.fork()
OSError: [Errno 12] Cannot allocate memory
ERROR


Traceback (most recent call last):
  File "<string>", line 1, in <module>
    from multiprocessing.forkserver import main; main(10, 11, ['__main__'], **{'sys_path': ['/root/buildarea/3.x.angelico-debian-amd64/build/target/lib/python315.zip', '/root/buildarea/3.x.angelico-debian-amd64/build/Lib', '/root/buildarea/3.x.angelico-debian-amd64/build/build/lib.linux-x86_64-3.15'], 'main_path': '/root/buildarea/3.x.angelico-debian-amd64/build/build/test_python_1406154æ/@test_1406154_tmpæ', 'authkey_r': 13})
                                                 ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 329, in main
    pid = os.fork()
OSError: [Errno 12] Cannot allocate memory
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/build/test_python_1406154æ/@test_1406154_tmpæ", line 4, in <module>
    with multiprocessing.Pool(200) as p:
         ~~~~~~~~~~~~~~~~~~~~^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/context.py", line 119, in Pool
    return Pool(processes, initializer, initargs, maxtasksperchild,
                context=self.get_context())
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/pool.py", line 215, in __init__
    self._repopulate_pool()
    ~~~~~~~~~~~~~~~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/pool.py", line 306, in _repopulate_pool
    return self._repopulate_pool_static(self._ctx, self.Process,
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
                                        self._processes,
                                        ^^^^^^^^^^^^^^^^
    ...<3 lines>...
                                        self._maxtasksperchild,
                                        ^^^^^^^^^^^^^^^^^^^^^^^
                                        self._wrap_exception)
                                        ^^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/pool.py", line 329, in _repopulate_pool_static
    w.start()
    ~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/process.py", line 121, in start
    self._popen = self._Popen(self)
                  ~~~~~~~~~~~^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/context.py", line 300, in _Popen
    return Popen(process_obj)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/popen_forkserver.py", line 35, in __init__
    super().__init__(process_obj)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/popen_fork.py", line 20, in __init__
    self._launch(process_obj)
    ~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/popen_forkserver.py", line 59, in _launch
    self.pid = forkserver.read_signed(self.sentinel)
               ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 395, in read_signed
    raise EOFError('unexpected EOF')
EOFError: unexpected EOF
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 340, in main
    code = _serve_one(child_r, fds,
                      unused_fds,
                      old_handlers)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 380, in _serve_one
    code = spawn._main(child_r, parent_sentinel)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/spawn.py", line 132, in _main
    self = reduction.pickle.load(from_parent)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/synchronize.py", line 117, in __setstate__
    self._semlock = _multiprocessing.SemLock._rebuild(*state)
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 340, in main
    code = _serve_one(child_r, fds,
                      unused_fds,
                      old_handlers)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 380, in _serve_one
    code = spawn._main(child_r, parent_sentinel)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/spawn.py", line 132, in _main
    self = reduction.pickle.load(from_parent)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/synchronize.py", line 117, in __setstate__
    self._semlock = _multiprocessing.SemLock._rebuild(*state)
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 340, in main
    code = _serve_one(child_r, fds,
                      unused_fds,
                      old_handlers)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 380, in _serve_one
    code = spawn._main(child_r, parent_sentinel)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/spawn.py", line 132, in _main
    self = reduction.pickle.load(from_parent)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/synchronize.py", line 117, in __setstate__
    self._semlock = _multiprocessing.SemLock._rebuild(*state)
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory
Traceback (most recent call last):
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 340, in main
    code = _serve_one(child_r, fds,
                      unused_fds,
                      old_handlers)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 340, in main
    code = _serve_one(child_r, fds,
                      unused_fds,
                      old_handlers)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 380, in _serve_one
    code = spawn._main(child_r, parent_sentinel)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/spawn.py", line 132, in _main
    self = reduction.pickle.load(from_parent)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/synchronize.py", line 117, in __setstate__
    self._semlock = _multiprocessing.SemLock._rebuild(*state)
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 340, in main
    code = _serve_one(child_r, fds,
                      unused_fds,
                      old_handlers)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 380, in _serve_one
    code = spawn._main(child_r, parent_sentinel)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/spawn.py", line 132, in _main
    self = reduction.pickle.load(from_parent)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/synchronize.py", line 117, in __setstate__
    self._semlock = _multiprocessing.SemLock._rebuild(*state)
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 380, in _serve_one
    code = spawn._main(child_r, parent_sentinel)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/spawn.py", line 132, in _main
    self = reduction.pickle.load(from_parent)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/synchronize.py", line 117, in __setstate__
    self._semlock = _multiprocessing.SemLock._rebuild(*state)
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 340, in main
    code = _serve_one(child_r, fds,
                      unused_fds,
                      old_handlers)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 380, in _serve_one
    code = spawn._main(child_r, parent_sentinel)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/spawn.py", line 132, in _main
    self = reduction.pickle.load(from_parent)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/synchronize.py", line 117, in __setstate__
    self._semlock = _multiprocessing.SemLock._rebuild(*state)
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory
---


Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/_test_multiprocessing.py", line 7021, in test_large_pool
    rc, out, err = script_helper.assert_python_ok(testfn)
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/support/script_helper.py", line 182, in assert_python_ok
    return _assert_python(True, *args, **env_vars)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/support/script_helper.py", line 167, in _assert_python
    res.fail(cmd_line)
    ~~~~~~~~^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/support/script_helper.py", line 80, in fail
    raise AssertionError(f"Process return code is {exitcode}\n"
    ...<10 lines>...
                         f"---")
AssertionError: Process return code is 1
command line: ['/root/buildarea/3.x.angelico-debian-amd64/build/python', '-X', 'faulthandler', '-I', '@test_1406154_tmpæ']


Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/contextlib.py", line 85, in inner
    return func(*args, **kwds)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/_test_multiprocessing.py", line 761, in test_many_processes
    p.start()
    ~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/process.py", line 121, in start
    self._popen = self._Popen(self)
                  ~~~~~~~~~~~^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/context.py", line 300, in _Popen
    return Popen(process_obj)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/popen_forkserver.py", line 35, in __init__
    super().__init__(process_obj)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/popen_fork.py", line 20, in __init__
    self._launch(process_obj)
    ~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/popen_forkserver.py", line 59, in _launch
    self.pid = forkserver.read_signed(self.sentinel)
               ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 395, in read_signed
    raise EOFError('unexpected EOF')
EOFError: unexpected EOF


Traceback (most recent call last):
  File "<string>", line 1, in <module>
    from multiprocessing.forkserver import main; main(10, 11, ['__main__'], **{'sys_path': ['/root/buildarea/3.x.angelico-debian-amd64/build/target/lib/python315.zip', '/root/buildarea/3.x.angelico-debian-amd64/build/Lib', '/root/buildarea/3.x.angelico-debian-amd64/build/build/lib.linux-x86_64-3.15'], 'main_path': '/root/buildarea/3.x.angelico-debian-amd64/build/build/test_python_1434974æ/@test_1434974_tmpæ', 'authkey_r': 13})
                                                 ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 329, in main
    pid = os.fork()
OSError: [Errno 12] Cannot allocate memory
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/build/test_python_1434974æ/@test_1434974_tmpæ", line 4, in <module>
    with multiprocessing.Pool(200) as p:
         ~~~~~~~~~~~~~~~~~~~~^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/context.py", line 119, in Pool
    return Pool(processes, initializer, initargs, maxtasksperchild,
                context=self.get_context())
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/pool.py", line 215, in __init__
    self._repopulate_pool()
    ~~~~~~~~~~~~~~~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/pool.py", line 306, in _repopulate_pool
    return self._repopulate_pool_static(self._ctx, self.Process,
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
                                        self._processes,
                                        ^^^^^^^^^^^^^^^^
    ...<3 lines>...
                                        self._maxtasksperchild,
                                        ^^^^^^^^^^^^^^^^^^^^^^^
                                        self._wrap_exception)
                                        ^^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/pool.py", line 329, in _repopulate_pool_static
    w.start()
    ~~~~~~~^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/process.py", line 121, in start
    self._popen = self._Popen(self)
                  ~~~~~~~~~~~^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/context.py", line 300, in _Popen
    return Popen(process_obj)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/popen_forkserver.py", line 35, in __init__
    super().__init__(process_obj)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/popen_fork.py", line 20, in __init__
    self._launch(process_obj)
    ~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/popen_forkserver.py", line 59, in _launch
    self.pid = forkserver.read_signed(self.sentinel)
               ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/multiprocessing/forkserver.py", line 395, in read_signed
    raise EOFError('unexpected EOF')
EOFError: unexpected EOF
---


Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/_test_multiprocessing.py", line 7021, in test_large_pool
    rc, out, err = script_helper.assert_python_ok(testfn)
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/support/script_helper.py", line 182, in assert_python_ok
    return _assert_python(True, *args, **env_vars)
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/support/script_helper.py", line 167, in _assert_python
    res.fail(cmd_line)
    ~~~~~~~~^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/support/script_helper.py", line 80, in fail
    raise AssertionError(f"Process return code is {exitcode}\n"
    ...<10 lines>...
                         f"---")
AssertionError: Process return code is 1
command line: ['/root/buildarea/3.x.angelico-debian-amd64/build/python', '-X', 'faulthandler', '-I', '@test_1434974_tmpæ']

@sobolevn
Copy link
Member

sobolevn commented Oct 3, 2025

Congrats, very useful speedup!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants