Seite 1 von 1

Performance-Vergleich C, Java und Python

Verfasst: Dienstag 19. Mai 2015, 16:58
von chrix
Hallo Zusammen,

im Versuch die Laufzeit von verschiedenen Programmiersprachen zu vergleichen hab ich versucht, Primzahlen berechnen zu lassen und die Laufzeit des Programms ausgeben zu lassen. Dabei sind mir gravierende Unterschiede aufgefallen:
Ich lasse alle Primzahlen bis 100.000 berechnen. Während C und Java alle Primzahlen innerhalb von 2-3 Sekunden berechnet haben, benötigt Python ca 240 Sekunden.

Worin liegt dieser gravierende Unterschied bzw. gibt es optimimierungen für Python?

Code: Alles auswählen

import time

def isPrime(num):
    loop = 2
    while num > loop :
        if num % loop == 0 and loop != num:
            return False
        loop += 1
    return True

maxNum = 100000
primelist = []
i = 0
end = 0
start = time.time()

for i in range(maxNum):
    if isPrime(i):
        primelist.append(i)
        
end = time.time()

for i in primelist:
    print(i)
print("Laufzeit: " + str(end - start))

Code: Alles auswählen

import java.util.ArrayList;
import java.util.List;


public class Calc {
	public static void main(String[] args) {

		int maxNum = 100000;
		List<Integer> liste = new ArrayList<Integer>();
		long end = 0;
		long start = System.nanoTime();

		for (int i = 0; i < maxNum; i++) {
			if (isPrime(i)) {
				liste.add(i);
			}
		}

		end = System.nanoTime();;
		for(int num : liste){
			System.out.println(num);
		}
		
		System.out.println("Laufzeit: " + (double)(end - start)/1000000000);

		return;
	}

	private static boolean isPrime(int num) {
		int loop = 2;
		while (num > loop) {
			if (num % loop == 0 && loop != num) {
				return false;
			}
			loop += 1;
		}
		return true;
	}
}

Re: Performance-Vergleich C, Java und Python

Verfasst: Dienstag 19. Mai 2015, 17:59
von darktrym
Benutz PyPy.

Re: Performance-Vergleich C, Java und Python

Verfasst: Dienstag 19. Mai 2015, 18:47
von jens
Und dann noch mehr stellen, damit der JIT richtig in Fahrt kommt...

Re: Performance-Vergleich C, Java und Python

Verfasst: Dienstag 19. Mai 2015, 19:28
von BlackJack
Oder vielleicht nicht so einen furchtbaren Algorithmus und vielleicht nicht gerade einen Vergleich bei dem zu erwarten ist das eine dynamische Programmiersprache wie Python einer statisch kompilierten unterlegen ist weil der aus grundlegenden Rechenoperationen mit ganze Zahlen auskommt die vom Prozessor direkt in einer engen Schleife ausgeführt werden können wenn man das zu nativem Code compilieren kann.

Re: Performance-Vergleich C, Java und Python

Verfasst: Mittwoch 20. Mai 2015, 08:25
von darktrym
Also, auf meinen beileibe nicht mehr aktuellen Notebook komme ich mit PyPy in die Sekundenregion(3,5s).

Re: Performance-Vergleich C, Java und Python

Verfasst: Mittwoch 20. Mai 2015, 08:42
von Sirius3
Naja, mit einem intelligenten Algorithmus schafft es Python in unter 0.005s. Da braucht schon das Kompilieren eines C oder Java Programms deutlich länger ;-)

Re: Performance-Vergleich C, Java und Python

Verfasst: Mittwoch 20. Mai 2015, 08:59
von bwbg
Das Verhältnis von 1:100 von statischer in Maschinencode (C, C++, Java, ...) zu einer dynamischen, interpretierten Sprache empfinde ich nicht als gravierend. 240 Sekunden mag subjektiv lang erscheinen, 2-3 Sekunden für das bisschen Rechnerei wären mir allerdings mit C und Derivaten auch zu langsam ;)

Etwas umgeschrieben braucht meine Desktop-Kiste mit CPython noch rund 10s.

Re: Performance-Vergleich C, Java und Python

Verfasst: Mittwoch 20. Mai 2015, 09:14
von jens
Das ganze ist ja eh praxisfern... Für number-crunching ist Python nicht gemacht.

Also was soll man eigentlich vergleichen?!?

Re: Performance-Vergleich C, Java und Python

Verfasst: Mittwoch 20. Mai 2015, 09:31
von darktrym
Er will ja vermutlich die Sprache vergleichen, nicht dessen Implementierung bzw. Dauer bei der Ausführung.
Sogesehen ist der Thread sinnfrei².

Re: Performance-Vergleich C, Java und Python

Verfasst: Mittwoch 20. Mai 2015, 09:44
von snafu
Und wenn man's ganz genau nimmt, dann sollte man auch nicht von einem Sprachvergleich sprechen, sondern von einem Vergleich der Compiler bzw Laufzeitumgebungen. Es wurde ja schon angesprochen, dass sich Python-Programme mit PyPy deutlich performanter verhalten können als mit CPython.

Und wenn man ein bißchen mehr Praxisbezug einbaut und sich in Python z.B. Unterstützung von NumPy holt, dann kann man für umfangreiche mathematische Berechnungen meistens auch nochmal einiges an Speed rausholen.

Fakt ist, dass Python nur sehr wenig am Code optimiert und aufgrund seiner dynamischen Natur vieles tut, was Java mit seinen statischen primitiven Typen nicht tun muss. Das macht sich besonders bemerkbar, wenn man viele Schleifendurchläufe hat, weil sich die zusätzlich benötigte Zeit dann eben spürbar aufsummiert.

Wie gesagt: PyPy kann hier schon weiterhelfen, da dort u.a. durch bestimmte Annahmen und fortgeschrittene Analyseverfahren an heiklen Stellen (sogenannte Hotspots) dafür gesorgt wird, dass trotz dynamischer Typisierung vieles am Ende eben doch wie bei statischer Typisierung behandelt werden kann. Mal als Beispiel: Eine Liste von Objekten mit prinzipiell total unterschiedlichen Typen könnte wie eine Liste mit Objekten vom Typ ``int`` behandelt werden, da man eben in aller Regel zwischen 20.000 Zahlen nicht plötzlich ein String-Objekt einbaut. Solche und andere Vorkehrungen verbessern dann dementsprechend die Performance beim Ausführen des Programms.

Re: Performance-Vergleich C, Java und Python

Verfasst: Mittwoch 20. Mai 2015, 12:20
von Hyperion
Ich habe neulich mal etwas von Numba gelesen... evtl. kann man damit auch noch Performance rauskitzeln?

Re: Performance-Vergleich C, Java und Python

Verfasst: Mittwoch 20. Mai 2015, 12:33
von kbr
Hyperion hat geschrieben:Ich habe neulich mal etwas von Numba gelesen... evtl. kann man damit auch noch Performance rauskitzeln?
Ja, kann man. Aber Python wählt man ohnehin nicht, um den schnellst möglichen Maschinencode zu erhalten, sondern um schnell funktionstüchtige Programme zu erstellen. Wenn es dann zu langsam ist und sich auch algorithmisch nichts mehr verbessern lässt, kann man je nach Anforderungen zu numpy oder numba etc. greifen oder eigene C-Extensions schreiben. Aber was erzähle ich hier ... :)

Re: Performance-Vergleich C, Java und Python

Verfasst: Mittwoch 20. Mai 2015, 14:43
von jens
Das Wiki Thema hab ich abgetrennt. Bitte bei http://www.python-forum.de/viewtopic.php?f=10&t=36326 dazu weiter machen :wink:

Aber mein Statement passt hier dennoch: Das Thema wäre eigentlich was für einen http://wiki.python-forum.de/FAQ Eintrag... :lol:

Re: Performance-Vergleich C, Java und Python

Verfasst: Mittwoch 20. Mai 2015, 17:04
von Ene Uran
Etwas zum Lachen ...

Code: Alles auswählen

import numpy as np

def np_primes1(limit):
    """
    returns a numpy array of primes, 2 <= p < limit
    """
    # create a sieve of ones
    is_prime = np.ones(limit + 1, dtype=np.bool)
    for n in range(2, int(limit**0.5 + 1.5)):
        if is_prime[n]:
            is_prime[n*n::n] = 0
    return np.nonzero(is_prime)[0][2:]

''' Resultat gemessen mit module timeit ...
np_primes1(100000) --> 0.295 milliseconds/pass
np_primes1(1000000) --> 3.107 milliseconds/pass
'''
Selbst ohne numpy ...

Code: Alles auswählen

def eras_dns(n):
    """
    returns  a list of primes 2 to < n
    """
    sieve = [True] * (n>>1)
    for x in range(3, int(n**0.5)+1, 2):
        if sieve[x>>1]:
            sieve[(x*x)>>1::x] = [False] * ((n-x*x-1)//(x<<1)+1)
    return [2] + [(x<<1)+1 for x in range(1, n>>1) if sieve[x]]

''' Resultat gemessen mit module timeit ...
eras_dns(100000)   --> 4.10 milliseconds/pass
eras_dns(1000000)  --> 41.48 milliseconds/pass
'''
Eine Variante von eras_dns(100000) in Go (Google supermodern C) braucht etwa 500 microseconds, so ist Python also immer noch etwas langsamer.

System iMac:
3.4.3 |Anaconda 2.2.0 (x86_64)| (default, Mar 6 2015, 12:07:41)
[GCC 4.2.1 (Apple Inc. build 5577)]