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

sergey-miryanov commented Apr 20, 2025

Updated results - only for remove resolve_slotdups (ran windows 11 x64 desktop, cpu- 11th Gen Intel(R) Core(TM) i5-11600K @ 3.90GHz):

Details
+---------------------------------------------------------------+---------+-----------------------+
| Benchmark                                                     | ref     | dups                  |
+===============================================================+=========+=======================+
| 1000-empty_cls                                                | 4.41 ms | 3.67 ms: 1.20x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_dunders                                         | 5.03 ms | 4.41 ms: 1.14x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A', 'B']                    | 5.49 ms | 4.77 ms: 1.15x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A', 'B']                          | 6.00 ms | 5.50 ms: 1.09x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A', 'B', 'D']               | 6.17 ms | 5.47 ms: 1.13x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A', 'B', 'D']                     | 6.71 ms | 6.18 ms: 1.09x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun']            | 5.29 ms | 4.72 ms: 1.12x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A_dun', 'B_dun']                  | 5.99 ms | 5.47 ms: 1.09x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun']   | 5.95 ms | 5.39 ms: 1.10x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun']         | 6.86 ms | 6.15 ms: 1.12x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['Logger']                    | 5.16 ms | 4.57 ms: 1.13x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['Logger']                          | 5.86 ms | 5.30 ms: 1.11x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['DatagramHandler']           | 6.32 ms | 5.65 ms: 1.12x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['DatagramHandler']                 | 6.93 ms | 6.42 ms: 1.08x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['MagicMock']                 | 7.24 ms | 6.79 ms: 1.07x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['MagicMock']                       | 7.87 ms | 7.70 ms: 1.02x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['Shelf']                     | 9.16 ms | 8.58 ms: 1.07x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['Shelf']                           | 9.84 ms | 9.37 ms: 1.05x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['tuple']                     | 5.53 ms | 4.19 ms: 1.32x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['tuple']                           | 6.17 ms | 4.99 ms: 1.24x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['dict']                      | 5.48 ms | 4.35 ms: 1.26x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['dict']                            | 6.14 ms | 5.10 ms: 1.20x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['list']                      | 5.88 ms | 4.30 ms: 1.37x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['list']                            | 6.55 ms | 5.10 ms: 1.28x faster |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls                                              | 443 ms  | 368 ms: 1.20x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_dunders                                       | 504 ms  | 440 ms: 1.14x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls_with_bases-bases=['A', 'B']                  | 547 ms  | 476 ms: 1.15x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_bases-bases=['A', 'B']                        | 606 ms  | 555 ms: 1.09x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls_with_bases-bases=['A', 'B', 'D']             | 615 ms  | 545 ms: 1.13x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_bases-bases=['A', 'B', 'D']                   | 673 ms  | 624 ms: 1.08x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls_with_bases-bases=['A_dun', 'B_dun']          | 531 ms  | 469 ms: 1.13x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_bases-bases=['A_dun', 'B_dun']                | 605 ms  | 552 ms: 1.10x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun'] | 598 ms  | 536 ms: 1.12x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun']       | 671 ms  | 621 ms: 1.08x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls_with_bases-bases=['Logger']                  | 520 ms  | 457 ms: 1.14x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_bases-bases=['Logger']                        | 588 ms  | 538 ms: 1.09x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls_with_bases-bases=['DatagramHandler']         | 630 ms  | 567 ms: 1.11x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_bases-bases=['DatagramHandler']               | 693 ms  | 644 ms: 1.08x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls_with_bases-bases=['MagicMock']               | 721 ms  | 673 ms: 1.07x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_bases-bases=['MagicMock']                     | 783 ms  | 751 ms: 1.04x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls_with_bases-bases=['Shelf']                   | 918 ms  | 865 ms: 1.06x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_bases-bases=['Shelf']                         | 998 ms  | 950 ms: 1.05x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls_with_bases-bases=['tuple']                   | 552 ms  | 420 ms: 1.31x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_bases-bases=['tuple']                         | 622 ms  | 503 ms: 1.24x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls_with_bases-bases=['dict']                    | 550 ms  | 434 ms: 1.27x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_bases-bases=['dict']                          | 616 ms  | 513 ms: 1.20x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls_with_bases-bases=['list']                    | 595 ms  | 431 ms: 1.38x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| 100000-cls_with_bases-bases=['list']                          | 656 ms  | 511 ms: 1.28x faster  |
+---------------------------------------------------------------+---------+-----------------------+
| Geometric mean                                                | (ref)   | 1.14x faster          |
+---------------------------------------------------------------+---------+-----------------------+

@sergey-miryanov
Copy link
Contributor Author

Updated results
+-------------------------------------------------------------+---------+-----------------------+
| Benchmark                                                   | ref2    | dups2                 |
+=============================================================+=========+=======================+
| 1000-empty_cls                                              | 4.41 ms | 3.68 ms: 1.20x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_dunders                                       | 5.08 ms | 4.53 ms: 1.12x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A', 'B']                  | 5.60 ms | 4.94 ms: 1.13x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A', 'B']                        | 6.14 ms | 5.58 ms: 1.10x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A', 'B', 'D']             | 6.31 ms | 5.66 ms: 1.12x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A', 'B', 'D']                   | 6.87 ms | 6.40 ms: 1.07x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun']          | 5.42 ms | 4.82 ms: 1.12x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A_dun', 'B_dun']                | 6.14 ms | 5.58 ms: 1.10x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun'] | 6.14 ms | 5.51 ms: 1.11x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun']       | 6.86 ms | 6.17 ms: 1.11x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['Logger']                  | 5.33 ms | 4.67 ms: 1.14x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['Logger']                        | 5.89 ms | 5.35 ms: 1.10x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['DatagramHandler']         | 6.46 ms | 5.78 ms: 1.12x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['DatagramHandler']               | 7.09 ms | 6.51 ms: 1.09x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['MagicMock']               | 7.38 ms | 6.86 ms: 1.07x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['MagicMock']                     | 7.98 ms | 7.58 ms: 1.05x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['Shelf']                   | 9.26 ms | 8.66 ms: 1.07x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['Shelf']                         | 9.91 ms | 9.43 ms: 1.05x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['tuple']                   | 5.60 ms | 4.31 ms: 1.30x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['tuple']                         | 6.25 ms | 5.03 ms: 1.24x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['dict']                    | 5.58 ms | 4.43 ms: 1.26x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['dict']                          | 6.20 ms | 5.18 ms: 1.20x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-empty_cls_with_bases-bases=['list']                    | 5.99 ms | 4.46 ms: 1.35x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 1000-cls_with_bases-bases=['list']                          | 6.64 ms | 5.16 ms: 1.29x faster |
+-------------------------------------------------------------+---------+-----------------------+
| 100000-empty_cls                                            | 442 ms  | 370 ms: 1.19x faster  |
+-------------------------------------------------------------+---------+-----------------------+
| Geometric mean                                              | (ref)   | 1.15x faster          |
+-------------------------------------------------------------+---------+-----------------------+

@sergey-miryanov
Copy link
Contributor Author

Results for this PR vs current main - 1.14x faster ``` +-------------------------------------------------------------+---------+-----------------------+ | Benchmark | ref5 | dups5 | +=============================================================+=========+=======================+ | 1000-empty_cls | 4.52 ms | 3.75 ms: 1.21x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_dunders | 5.20 ms | 4.64 ms: 1.12x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-empty_cls_with_bases-bases=['A', 'B'] | 5.74 ms | 5.00 ms: 1.15x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_bases-bases=['A', 'B'] | 6.33 ms | 5.72 ms: 1.11x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-empty_cls_with_bases-bases=['A', 'B', 'D'] | 6.53 ms | 5.73 ms: 1.14x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_bases-bases=['A', 'B', 'D'] | 7.03 ms | 6.42 ms: 1.09x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun'] | 5.47 ms | 4.96 ms: 1.10x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_bases-bases=['A_dun', 'B_dun'] | 6.25 ms | 5.73 ms: 1.09x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-empty_cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun'] | 6.22 ms | 5.67 ms: 1.10x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_bases-bases=['A_dun', 'B_dun', 'D_dun'] | 7.14 ms | 6.34 ms: 1.13x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-empty_cls_with_bases-bases=['Logger'] | 5.34 ms | 4.78 ms: 1.12x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_bases-bases=['Logger'] | 6.04 ms | 5.43 ms: 1.11x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-empty_cls_with_bases-bases=['DatagramHandler'] | 6.70 ms | 5.95 ms: 1.13x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_bases-bases=['DatagramHandler'] | 7.19 ms | 6.58 ms: 1.09x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-empty_cls_with_bases-bases=['MagicMock'] | 7.97 ms | 7.04 ms: 1.13x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_bases-bases=['MagicMock'] | 8.31 ms | 7.68 ms: 1.08x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-empty_cls_with_bases-bases=['Shelf'] | 9.50 ms | 8.90 ms: 1.07x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_bases-bases=['Shelf'] | 10.1 ms | 9.67 ms: 1.05x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-empty_cls_with_bases-bases=['tuple'] | 5.68 ms | 4.42 ms: 1.29x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_bases-bases=['tuple'] | 6.40 ms | 5.43 ms: 1.18x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-empty_cls_with_bases-bases=['dict'] | 5.69 ms | 4.62 ms: 1.23x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_bases-bases=['dict'] | 6.32 ms | 5.38 ms: 1.17x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-empty_cls_with_bases-bases=['list'] | 6.07 ms | 4.59 ms: 1.32x faster | +-------------------------------------------------------------+---------+-----------------------+ | 1000-cls_with_bases-bases=['list'] | 6.67 ms | 5.32 ms: 1.25x faster | +-------------------------------------------------------------+---------+-----------------------+ | Geometric mean | (ref) | 1.14x faster | +-------------------------------------------------------------+---------+-----------------------+ ```

@Yhg1s May I ask you a favor to run benchmarks on this PR too?

Copy link
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

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

Thanks!

Maybe @mdboom will be interested in running benchmarks for this PR?

@mdboom
Copy link
Contributor

mdboom commented May 1, 2025

Thanks!

Maybe @mdboom will be interested in running benchmarks for this PR?

Yep, I'm kicking it off now. Results may take a few hours (the queue gets long this time of year).

Co-authored-by: sobolevn <mail@sobolevn.me>
@sergey-miryanov
Copy link
Contributor Author

@sobolevn @mdboom Thanks a lot!

@mdboom
Copy link
Contributor

mdboom commented May 1, 2025

Overall on pyperformance, it's a wash. Some benchmarks are 10% faster, but we should probably also understand why some are 5% slower, to make sure there aren't negative effects of this change. (Ignore the gc_traversal benchmark, that is not particularly reliable).

@sergey-miryanov
Copy link
Contributor Author

@mdboom Thank you! Will profile slow benchmarks.

@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          |
+-------------------------------------------------------------+---------+-----------------------+

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

Successfully merging this pull request may close these issues.

6 participants