0

I was making some fibonacci calculations with PyPy, first i started with bigger numbers, PyPy was a little bit faster, but with small numbers it gives nearly the same performance and some cases normal interpreter is much more faster than pypy is there a spesific reason why?

from time import time

def fibonacci(n):
    a, b = 0, 1
    for i in range(0, n):
        a, b = b, a + b
    return a
start = time()
result = fibonacci(5000)
end = time()
print(end-start) 

With a small number like 5000 Python is actually faster than PyPy;

Python: 0.0006256103515625
PyPy: 0.0016071796417236328

When it comes to a bigger slightly bigger number like 1.000.000, PyPy is faster than Python

PyPy: 8.567905902862549
Python: 9.79963207244873

But when it comes to a different calculation like:

def sum_in_range(a,b):
    c = 0
    for i in range(1, a):
       for j in range(1, b):
          c += i+j
    return c

start = time()
result = sum_in_range(100000,100000)
end = time()
print(end-start)

PyPy is 60 times faster than Python

PyPy: 0.1999509334564209
Python: 12.051937103271484
Yagiz Degirmenci
  • 16,595
  • 7
  • 65
  • 85
  • 3
    From PyPy's performance page (https://www.pypy.org/performance.html): *"[...] the JIT is known not to work on [...] Really short-running scripts: A rule of thumb is if something runs below 0.2s the JIT has no chance"* - your execution time is simply too short for PyPy's JIT to outperform regular CPython – UnholySheep Jun 26 '20 at 21:02
  • @Carcigenicate also tried that too `timeit('fibonacci(100)','from __main__ import fibonacci')` the result was nearly the same – Yagiz Degirmenci Jun 26 '20 at 21:03
  • @UnholySheep but also with a number like 500.000 python still wins... both of them ends with over 2 seconds. – Yagiz Degirmenci Jun 26 '20 at 21:15

2 Answers2

3

In addition to the other answer(s): your fibonacci example would run at roughly the same speed if it was written in C, C#, in Python with or without a JIT, or anywhere else. That's because the fibonacci example makes exponentially large numbers. After a few iterations it is spending all the time inside the library handling ever larger integers, and almost none outside it.

Of course we can discuss the finer points of why it is a bit faster or slower in this or this case, but that's comparing small constant overheads and details of the long-integer libraries used; it has little to do with the language.

Armin Rigo
  • 12,048
  • 37
  • 48
2

The pypy JIT needs a little bit of time to initialize and will work better with repeat results. To illustrate with a slightly different version of the code:

from __future__ import print_function
import sys
from datetime import datetime


def fibonacci(n):
    a, b = 0, 1
    for i in range(0, n):
        a, b = b, a + b
    return a

n = int(sys.argv[1])
runs = int(sys.argv[2])
durations = []
for i in range(runs):
    start = datetime.now()
    fibonacci(int(n))
    durations.append(datetime.now() - start)

durations.sort()

print('min:', durations[0])
print('median:', durations[int(runs / 2)])
print('max:', durations[-1])

And running it on a few Python versions:

# python2 --version
Python 2.7.18rc1
# python2 fib.py 5000 1000
min: 0:00:00.000303
median: 0:00:00.000307
max: 0:00:00.001273
# python2 fib.py 1000000 5
min: 0:00:05.711701
median: 0:00:05.782151
max: 0:00:05.850577

# python3 --version
Python 3.8.2
# python3 fib.py 5000 1000
min: 0:00:00.000305
median: 0:00:00.000309
max: 0:00:00.001254
# python3 fib.py 1000000 5
min: 0:00:05.796954
median: 0:00:05.825557
max: 0:00:05.841489

# pypy --version
Python 2.7.13 (7.3.1+dfsg-2, Apr 21 2020, 05:05:41)
[PyPy 7.3.1 with GCC 9.3.0]
# pypy fib.py 5000 1000
min: 0:00:00.000160
median: 0:00:00.000179
max: 0:00:00.002456
# pypy fib.py 1000000 5
min: 0:00:04.314290
median: 0:00:04.405727
max: 0:00:04.453215
Wolph
  • 78,177
  • 11
  • 137
  • 148