pypy / pypy

PyPy is a very fast and compliant implementation of the Python language.
https://pypy.org
Other
902 stars 47 forks source link

Performance loss with deeply nested generators #2779

Open gitlab-importer opened 6 years ago

gitlab-importer commented 6 years ago

In Heptapod by bitbucket_importer on Mar 29, 2018, 22:25

Created originally on Bitbucket by Hrvoje Nikšić

PyPy (5.10.1) is significantly slower than CPython (3.6.3) on the attached benchmark.

The script profiles traversing generators nested with yield from at various depths, which also comes up when suspending and resuming recursive or nested async functions. I was curious whether PyPy optimizes yield from delegation as mentioned in the original PEP and later in a message by Guido. It seems that CPython dropped the optimization due to an issue with tracebacks.

It looks like PyPy doesn't implement the optimization either - but that is not the topic of this issue. I noticed a sharp slowdown in PyPy at the nesting depth of around 80. At that point the performance suddenly drops to levels significantly slower than CPython. For example, on my machine, with depth == 100:

$ python3 benchnestedyield.py 100
0.061139583587646484
0.06133460998535156
0.06076836585998535
0.06116318702697754
0.061196327209472656

$ pypy3 benchnestedyield.py  100
0.30632662773132324
0.31490111351013184
0.29983067512512207
0.31607627868652344
0.31775617599487305

$ pypy3 --jit off benchnestedyield.py  100
0.16022372245788574
0.1604137420654297
0.16206026077270508
0.161407470703125
0.16135311126708984

With depth == 50, the numbers look like something I'd expect when comparing PyPy and CPython:

$ python3 benchnestedyield.py 50
0.029144287109375
0.029152870178222656
0.02940988540649414
0.02889084815979004
0.028936386108398438

$ pypy3 benchnestedyield.py  50
0.12029409408569336
0.005949974060058594
0.005345821380615234
0.005307197570800781
0.005133867263793945

$ pypy3 --jit off benchnestedyield.py 50
0.08134770393371582
0.08192563056945801
0.08233189582824707
0.08091974258422852
0.08127617835998535

This is probably not a big issue in practice, but I wanted to report it in case it's an anomaly someone cares to investigate.

Attachments: benchnestedyield.py

gitlab-importer commented 6 years ago

In Heptapod by @cfbolz on Mar 30, 2018, 09:45

It should definitely be fixed. If the depth is too deep, the traces get too long, then it aborts the trace, then it starts again. It never stops trying to create a trace (which is wrong).

gitlab-importer commented 3 years ago

In Heptapod by @cfbolz on Apr 30, 2021, 15:41

this is another bug that shows the problem of #3402!

gitlab-importer commented 1 year ago

In Heptapod by @cfbolz on Apr 30, 2023, 16:43

looking at this again, #3402 should have fixed this problem but doesn't. I wonder why the same approach doesn't work here :-(