Skip to content

Code runs 77x times slower when using Decimal running with coverage.py on PyPy 3.9 (7.3.8) #1339

Closed
@felipou

Description

@felipou

Describe the bug
Running with coveragepy on PyPy drastically slows down programs using Decimal:

~/tmp/pypyperftest$ time poetry run coverage run -m covperftest.covperftest 10000000
10000000

real	7m37,942s
user	7m36,118s
sys	0m1,348s
~/tmp/pypyperftest$ time poetry run python -m covperftest.covperftest 10000000
10000000

real	0m5,891s
user	0m5,267s
sys	0m0,606s

I've noticed this issue while experimenting with PyPy's newest versions in the past, trying to migrate to Python 3.8. At the time I didn't pay much attention, just gave up. Now that PyPy launched a new version supporting 3.9, I tried to investigate a bit more and got the results above. At first I thought that maybe it was because PyPy is using Decimal with a pure Python implementation, but forcing the C implementation yields similar results (if not slower).

To Reproduce

  1. What version of Python are you using?
    • Pypy 3.9 (7.3.8) - but I've noticed this problem while using earlier versions of PyPy.
  2. What version of coverage.py shows the problem?
    • I tested with the latest release, version 6.3.2.
  3. What versions of what packages do you have installed?
    • I tried to test in a virtualenv with as few packages as possible:
cffi==1.15.0
coverage==6.3.2
covperftest==1.0.0
greenlet==0.4.13
hpy==0.0.3
readline==6.2.4.1
tomli==2.0.1
  1. What code shows the problem?
    • I'm not sure where the problem in coveragepy is (or if there's even a problem at all, maybe it's something related to how Decimal works on PyPy, but I thought it would be better to report this here).
  2. What commands did you run?
    • I created a sample script to test this, which I executed in a virtualenv managed using poetry:
import random
import sys
from decimal import Decimal

size = int(sys.argv[1]) if len(sys.argv) > 1 else 100000

values = []
for _ in range(size):
    values.append(Decimal(3) * random.randint(0, 10000))
print(len(values), file=sys.stderr)

Expected behavior
Although a worse performance is to be expected when getting the coverage, it gets much worse when using Decimal. I tried the same code using just an integer, and the execution time was around 4.5x slower when using coveragepy. But when using Decimal, it was 77x slower.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpypy

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions