Seite 1 von 1
Nuitka vs. PyPy vs. Cython+gcc vs. CPython - Geschwindigkeit
Verfasst: Freitag 29. Dezember 2017, 20:54
von noisefloor
Hallo,
habe mal ein wenige mit
Nuitka rumgespielt. Und mich über die nicht vorhandene Geschwindigkeit (bei meinem Test) gewundert.
Der Testcode ist ein Test auf Primzahlen aus der Python Doku zu concurrent.futures (
Link):
Code: Alles auswählen
import math
PRIMES = [
112272535095293,
112582705942171,
112272535095293,
115280095190773,
115797848077099,
1099726899285419,
777777722155555333,
777777722155555335,
9999999900000001,
2327074306453592351,
2327074306453592353]
def is_prime(n):
if n % 2 == 0:
return False
sqrt_n = int(math.floor(math.sqrt(n)))
for i in range(3, sqrt_n + 1, 2):
if n % i == 0:
return False
return True
def main():
for number in PRIMES:
prime = is_prime(number)
print('{} is prime: {}'.format(number, prime))
if __name__ == '__main__':
main()
Geschwindigkeiten auf meinen System (Ubuntu 16.04, ruhender Desktop, Intel® Core i5-5200U CPU @ 2.20GHz × 4 ):
CPython 3.5: 3 min 23 s
CPython 3.5 + concurrent.futures.ProcessPoolExecutor: 2 min 15 s
PyPy3.5 v5.10.0: 0 min 24 s
Cython+gcc: 2 min 39 s
Nuitka: 3 min 7 s
PyPy ist als drastisch schneller als alles andere. Nur ist Nuitka ja kaum schneller als CPython. Hat dafür jemand eine Erklärung? Ist mein (zugegebener Maßen simpler) Test "schlecht"? Wobei das andere kompilierte Programm mit Cython+gcc ja eine ganze Ecke schneller ist (aber immer noch drastisch langsamer als Nuitka). Übersetzt habe ich mit `nuitka --standalone prime_code_linear.py`.
Gruß, noisefloor
Re: Nuitka vs. PyPy vs. Cython+gcc vs. CPython - Geschwindigkeit
Verfasst: Freitag 29. Dezember 2017, 23:48
von Sirius3
@noisefloor: ich glaube »Nuitka« ist noch ein einem so frühen Stadium, dass es noch nicht wirklich optimiert. Bei mir beschleunigt »numba« von 4min 16s auf 0min 16s.
Re: Nuitka vs. PyPy vs. Cython+gcc vs. CPython - Geschwindigkeit
Verfasst: Samstag 30. Dezember 2017, 00:23
von snafu
Nuitka wirkt wie eine Verschmelzung aus Py2Exe (und ähnliche Tools) mit PyPy, nur dass anscheinend das Rad für beide Bereiche neu erfunden wird. Was soll daran interessant sein? Oder übersehe ich was?
Re: Nuitka vs. PyPy vs. Cython+gcc vs. CPython - Geschwindigkeit
Verfasst: Samstag 30. Dezember 2017, 02:34
von DasIch
Nuitka ist momentan effektiv nichts anderes als CPython ohne den Interpreter Loop der durch den Bytecode geht und die korrespondierenden Funktionen aufruft. Nuitka ist nur schneller weil es etwas Overhead eliminiert, nicht weil es irgendwelche nennenswerten Optimierungen macht.
Re: Nuitka vs. PyPy vs. Cython+gcc vs. CPython - Geschwindigkeit
Verfasst: Samstag 30. Dezember 2017, 08:24
von noisefloor
Hallo,
ok, Danke für die Antworten.
@Sirius3: kannst du mal posten, wie du das mit Numba gemacht hast bzw wie du den Code für Numba modifiziert hast?
Gruß, noisefloor
Re: Nuitka vs. PyPy vs. Cython+gcc vs. CPython - Geschwindigkeit
Verfasst: Samstag 30. Dezember 2017, 09:33
von noisefloor
Hallo,
so, habe mir doch mal Numba via Miniconda installiert. Im oben gezeigten Code habe ich nur `from numba import jit` hinzugefügt und nur die `is_prime` Funktion mit `@jit` dekoriert.
Laufzeit: 0 min 19 s
Ist also am schnellsten.
Hat noch jemand eine Idee, warum die nach C kompilierte Version mit Cython + gcc auch relativ langsam ist?
Gruß, noisefloor
Re: Nuitka vs. PyPy vs. Cython+gcc vs. CPython - Geschwindigkeit
Verfasst: Samstag 30. Dezember 2017, 10:11
von nezzcarth
noisefloor hat geschrieben:
Hat noch jemand eine Idee, warum die nach C kompilierte Version mit Cython + gcc auch relativ langsam ist?
Hast du deinen Code oben unverändert mit Cython in eine Library verwandelt, oder zusätzlich statische Typen angegeben? Mit Typ-Deklarationen (für i, n und is_prime) ist es bei mir ein paar Sekunden schneller als pypy.
Re: Nuitka vs. PyPy vs. Cython+gcc vs. CPython - Geschwindigkeit
Verfasst: Samstag 30. Dezember 2017, 12:37
von noisefloor
Hallo,
@nezzcarth: nee, 1:1 übernommen, als `cython3 --embed meinprogramm.py`
Wie hast du den Code denn geändert, damit statische Type genutzt werden?
Gruß, noisefloor
Re: Nuitka vs. PyPy vs. Cython+gcc vs. CPython - Geschwindigkeit
Verfasst: Samstag 30. Dezember 2017, 13:02
von nezzcarth
@noisefloor:
Ich habe mit Cython nur sehr wenig Erfahrung und weiß daher nicht, ob das der richtige Weg ist. Folgendes habe ich gemacht:
[codebox=python file=primes.pyx]
import math
cdef bint is_prime(long n):
cdef int i
if n % 2 == 0:
return False
sqrt_n = int(math.floor(math.sqrt(n)))
for i in range(3, sqrt_n + 1, 2):
if n % i == 0:
return False
return True
def test_primes():
PRIMES = [
112272535095293,
112582705942171,
112272535095293,
115280095190773,
115797848077099,
1099726899285419,
777777722155555333,
777777722155555335,
9999999900000001,
2327074306453592351,
2327074306453592353]
for number in PRIMES:
prime = is_prime(number)
print('{} is prime: {}'.format(number, prime))
[/code]
Dies habe ich übersetzt mit 'cythonize -i primes.pyx' und die resultierende Library in ein Wrapper-Script importiert, das einfach nur 'test_primes' aufruft. Die Laufzeit beträgt so um die 13.5 Sekunden. Pypy braucht mit deinem Original-Skript c.a. 18 Sekunden.
Re: Nuitka vs. PyPy vs. Cython+gcc vs. CPython - Geschwindigkeit
Verfasst: Samstag 30. Dezember 2017, 13:26
von noisefloor
Hallo,
ah, ok. Hab's mal so ähnlich gemacht:
Code: Alles auswählen
import math
PRIMES = [
112272535095293,
112582705942171,
112272535095293,
115280095190773,
115797848077099,
1099726899285419,
777777722155555333,
777777722155555335,
9999999900000001,
2327074306453592351,
2327074306453592353]
cdef bint is_prime(long n):
cdef int sqrt_n, i
if n % 2 == 0:
return False
sqrt_n = int(math.floor(math.sqrt(n)))
for i in range(3, sqrt_n + 1, 2):
if n % i == 0:
return False
return True
def main():
cdef long number
cdef bint prime
for number in PRIMES:
prime = is_prime(number)
print('{} is prime: {}'.format(number, prime))
if __name__ == '__main__':
main()
Laufzeit: 0 min 18 s
Also die kürzeste Laufzeit. Wobei sich zumindest in diesem Fall der Mehraufwand gegenüber PyPy IMHO nicht wirklich lohnt.
Gruß, noisefloor
Re: Nuitka vs. PyPy vs. Cython+gcc vs. CPython - Geschwindigkeit
Verfasst: Samstag 30. Dezember 2017, 15:37
von DasIch
Der Cython Code funktioniert dann auch nur noch mit longs, tut also auch nicht dass gleiche. Außerdem muss bei PyPy der JIT erstmal warm werden, dies misst du hier mit spielt aber in der Praxis häufig gar keine Rolle.