Warum sind Python-Programme oft langsamer als das in C oder C ++ geschriebene äquivalente Programm?

72

Warum scheint Python im Durchschnitt langsamer als C / C ++? Ich habe Python als meine erste Programmiersprache gelernt, aber ich habe gerade erst mit C angefangen und habe bereits das Gefühl, einen deutlichen Unterschied zu erkennen.

Riemannliness
quelle
14
Ist Ihnen bewusst, dass Python interpretiert wird?
S.Lott
9
@ kaizer.se - dann müssen wir auch die anderen offensichtlichen Wahrheiten sagen, wir arbeiten nicht mit Programmiersprachen, wir arbeiten mit Programmiersprachenimplementierungen; etc etc
igouy
6
@ kaizer.se: ja, wir wissen, wir wissen. Aber denken Sie nur daran, wie umständlich es ist, zu schreiben, während Sie Kommentare wie Ihre vermeiden. "Warum ist Python-Code (mit einem gängigen Interpreter ausgeführt) so langsam?"
Cascabel
6
Nach vielen Diskussionen hat diese Frage eine zweite Chance erhalten. Ich habe den Ton bearbeitet, um sein (erneutes) Schließen und (erneutes) Löschen zu verhindern. Es wundert mich, dass keiner der 1000 Zuschauer dieser Frage, von denen viele die Frage oder die Antworten abgestimmt haben, es für angebracht hielt, den Grund für die Schließung zu bestreiten oder den argumentativen Ton der Frage festzulegen.
ire_and_curses

Antworten:

87

Python ist eine höhere Sprache als C, dh es abstrahiert die Details des Computers von Ihnen - Speicherverwaltung, Zeiger usw. - und ermöglicht es Ihnen, Programme auf eine Weise zu schreiben, die dem menschlichen Denken näher kommt.

Es ist wahr, dass C-Code normalerweise 10 bis 100 Mal schneller ausgeführt wird als Python-Code, wenn Sie nur die Ausführungszeit messen. Wenn Sie jedoch auch die Entwicklungszeit einbeziehen, schlägt Python häufig C. Bei vielen Projekten ist die Entwicklungszeit weitaus kritischer als die Laufzeitleistung. Eine längere Entwicklungszeit führt direkt zu zusätzlichen Kosten, weniger Funktionen und einer langsameren Markteinführungszeit.

Intern wird Python-Code langsamer ausgeführt, weil der Code zur Laufzeit interpretiert wird, anstatt zur Kompilierungszeit zu nativem Code kompiliert zu werden.

Andere interpretierte Sprachen wie Java-Bytecode und .NET-Bytecode werden schneller ausgeführt als Python, da die Standarddistributionen einen JIT-Compiler enthalten , der zur Laufzeit Bytecode zu nativem Code kompiliert. Der Grund, warum CPython noch keinen JIT-Compiler hat, liegt darin, dass die Dynamik von Python das Schreiben eines solchen erschwert. Es gibt Arbeit in Fortschritt eine schnellere Python - Laufzeit zu schreiben , so dass Sie die Performance - Lücke in Zukunft reduziert werden erwarten sollten, aber es wird wahrscheinlich eine Weile dauern , bis die Standard - Python - Distribution einen leistungsstarken JIT - Compiler enthält.

Mark Byers
quelle
43
Um pedantisch zu sein: Python wird normalerweise zur Kompilierungszeit nicht zu nativem Code kompiliert. Python-Bytecode muss noch interpretiert werden.
Mark Byers
20
Sie haben nicht wirklich erklärt, warum Python-Implementierungen so CPU-hungrig sind. Sie können all das abstrahieren, ohne zur Laufzeit allzu viele Kosten zu verursachen. Es ist die extrem dynamische Natur von Python, die die gesamte CPU verbraucht: All diese Attribut-Lookups / Methoden-Dispatches summieren sich und machen selbst JITs eine ziemlich schwere Zeit - und Python wird im Moment normalerweise ohne JIT verwendet.
SamB
@SamB: Ich habe jetzt einen Vergleich mit anderen interpetierten Sprachen hinzugefügt, um Ihren Standpunkt anzusprechen. Der Teil, den ich über Abstinktionen schrieb, war nicht zu erklären, warum Python langsamer ausgeführt wird, sondern zu erklären, warum es schneller zu programmieren sein kann.
Mark Byers
2
Rückblickend denke ich, dass es sich lohnt, die globale Interpretersperre und die Art und Weise zu beachten, wie alle Objekte in Python Heap-zugewiesene Objekte sind, sogar eine einfache Ganzzahl. Ohne auf spezifische Implementierungsdetails einzugehen, können diese Arten von Dingen, abgesehen von den übergeordneten Abstraktionen, die Leistung ziemlich stark belasten. Trotzdem denke ich immer noch, dass die meisten Anwendungen hauptsächlich in einer Skriptsprache wie Python geschrieben werden sollten. Wie Knuth über vorzeitige Optimierung feststellt, sind nur kleine Teile der meisten Anwendungen tatsächlich sehr leistungskritisch.
stinky472
+1 [Ehrlich gesagt, deshalb lerne ich Python, um meine Produktionssoftware zu beschleunigen, wo der Chef Geschwindigkeit in der Entwicklung verlangt] - "Es ist wahr, dass C-Code normalerweise 10 bis 100 Mal schneller ausgeführt wird als Python-Code, wenn Sie nur die Ausführung messen Wenn Sie jedoch auch die Entwicklungszeit einbeziehen, schlägt Python häufig C. Bei vielen Projekten ist die Entwicklungszeit weitaus kritischer als die Laufzeitleistung. Eine längere Entwicklungszeit führt direkt zu zusätzlichen Kosten, weniger Funktionen und einer langsameren Markteinführungszeit. "
48

CPython ist besonders langsam, da es kein Just-in-Time-Optimierungsprogramm gibt (da es sich um die Referenzimplementierung handelt und in bestimmten Fällen Einfachheit gegenüber Leistung wählt). Unladen Swallow ist ein Projekt zum Hinzufügen einer LLVM-gestützten JIT zu CPython und erzielt massive Beschleunigungen. Es ist möglich, dass Jython und IronPython viel schneller als CPython sind und von stark optimierten virtuellen Maschinen (JVM und .NET CLR) unterstützt werden.

Eine Sache, die Python jedoch wahrscheinlich langsamer machen wird, ist, dass es dynamisch typisiert wird und es für jeden Attributzugriff eine Menge Suche gibt.

Zum Beispiel führt das Aufrufen feines Objekts Azu möglichen Suchvorgängen __dict__, Aufrufen __getattr__usw. und schließlich zum Aufrufen __call__des aufrufbaren Objekts f.

In Bezug auf die dynamische Typisierung gibt es viele Optimierungen, die durchgeführt werden können, wenn Sie wissen, mit welcher Art von Daten Sie es zu tun haben. Wenn Sie beispielsweise in Java oder C ein gerades Array von Ganzzahlen haben, die Sie summieren möchten, kann der Endassembler-Code so einfach sein, dass Sie den Wert am Index iabrufen, zum Index hinzufügen accumulatorund dann inkrementieren i.

In Python ist es sehr schwierig, Code so optimal zu machen. Angenommen, Sie haben ein Listenunterklassenobjekt, das ints enthält. Bevor Python überhaupt etwas hinzufügt, muss es aufrufen list.__getitem__(i), dies dann durch Aufrufen zum "Akkumulator" hinzufügen und accumulator.__add__(n)dann wiederholen. Hier können Tonnen von alternativen Suchvorgängen auftreten, weil ein anderer Thread beispielsweise die __getitem__Methode, das Diktat der Listeninstanz oder das Diktat der Klasse zwischen Aufrufen zum Hinzufügen oder Abrufen geändert hat. Selbst das Auffinden des Akkumulators und der Liste (und aller von Ihnen verwendeten Variablen) im lokalen Namespace führt zu einer Diktatsuche. Der gleiche Aufwand gilt für die Verwendung eines benutzerdefinierten Objekts, obwohl er für einige integrierte Typen etwas geringer ist.

Es ist auch erwähnenswert, dass die primitiven Typen wie bigint (int in Python 3, long in Python 2.x), list, set, dict usw. usw. in Python häufig verwendet werden. Es gibt Tonnen von eingebauten Operationen an diesen Objekten, die bereits ausreichend optimiert sind. Im obigen Beispiel würden Sie beispielsweise nur aufrufen, sum(list)anstatt einen Akkumulator und einen Index zu verwenden. Wenn Sie sich an diese halten und ein bisschen mit int / float / complex Zahlen knacken, werden Sie im Allgemeinen keine Geschwindigkeitsprobleme haben, und wenn Sie dies tun, gibt es wahrscheinlich eine kleine zeitkritische Einheit (zum Beispiel eine SHA2-Digest-Funktion), die Sie können Wechseln Sie einfach zu C (oder Java-Code in Jython). Tatsache ist, dass Sie beim Codieren von C oder C ++ viel verschwenden werdenZeit, Dinge zu tun, die Sie in wenigen Sekunden / Zeilen Python-Code tun können. Ich würde sagen, der Kompromiss lohnt sich immer, außer in Fällen, in denen Sie so etwas wie Embedded- oder Echtzeitprogrammierung durchführen und es sich nicht leisten können.

L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
quelle
Verwendet Unladen Swallow derzeit nicht etwas mehr Speicher? Die Ergebnisse des zweiten Quartals 2009 [ code.google.com/p/unladen-swallow/wiki/Release2009Q2] besagen, dass der Speicher um das 10- fache erhöht wurde, und das dritte Quartal 2009 [ code.google.com/p/unladen-swallow/wiki/Release2009Q3] gibt an, dass sie es erhalten haben um 930% gesunken (nicht sicher, wie diese Zahl zu interpretieren ist). Es klingt so, als wäre ein geringerer Speicher ein Ziel, das aber noch nicht erreicht wurde.
Brendan Long
doh, dieser Satz, den ich geschrieben habe, ergab sowieso keinen Sinn.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
"Eine Sache, die Python wahrscheinlich langsamer machen wird, ist, dass es dynamisch typisiert wird und es für jeden Attributzugriff eine Menge Nachschlagewerke gibt." Hier gewinnt die JIT in PyPy wirklich. Die JIT kann feststellen, dass Ihr Code etwas unkompliziertes und einfaches tut, und kann auf einige einfache Maschinenanweisungen optimieren. Somit ist PyPy jetzt viel schneller als CPython, wenn Sie etwas Einfaches in einer Schleife tun.
Steveha
19

Kompilierung und Interpretation sind hier nicht wichtig: Python wird kompiliert und ist ein winziger Teil der Laufzeitkosten für jedes nicht triviale Programm.

Die Hauptkosten sind: das Fehlen eines Integer-Typs, der nativen Integers entspricht (wodurch alle Integer-Operationen erheblich teurer werden), das Fehlen einer statischen Typisierung (was die Auflösung von Methoden erschwert und bedeutet, dass die Wertetypen überprüft werden müssen zur Laufzeit) und das Fehlen von Werten ohne Box (die die Speichernutzung reduzieren und eine Indirektionsebene vermeiden können).

Nicht, dass eines dieser Dinge in Python nicht möglich ist oder nicht effizienter gestaltet werden kann, aber es wurde die Wahl getroffen, den Komfort und die Flexibilität des Programmierers sowie die Sprachbereinigung gegenüber der Laufzeitgeschwindigkeit zu bevorzugen. Einige dieser Kosten können durch eine clevere JIT-Kompilierung überwunden werden, aber die Vorteile, die Python bietet, sind immer mit Kosten verbunden.


quelle
1
Bessere Antwort als die akzeptierte, obwohl es wichtig ist zu beachten, dass Python nicht immer kompiliert wird. Es ist wirklich die Implementierung. Es wird nach meiner Erfahrung meistens interpretiert.
Triforcey
9

Der Unterschied zwischen Python und C ist der übliche Unterschied zwischen einer interpretierten (Bytecode) und einer kompilierten (in die Muttersprache) Sprache. Persönlich sehe ich Python nicht so langsam, es schafft es ganz gut. Wenn Sie versuchen, es außerhalb seines Bereichs zu verwenden, wird es natürlich langsamer. Dafür können Sie jedoch C-Erweiterungen für Python schreiben, die zeitkritische Algorithmen in nativen Code einfügen und so viel schneller machen.

Femaref
quelle
2
s / es ist / sein. Interpretiert oder kompiliert bedeutet nichts in Bezug auf Optimierbarkeit. JVM und C können entweder interpretiert oder kompiliert werden. In beiden Fällen können unterschiedliche Optimierungen angewendet werden (adaptive Optimierung vs. Kompilierungszeit + LTO)
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
4
Python wird zu Bytecode kompiliert, der dann interpretiert wird. Es kann auch zu Maschinencode kompiliert werden, sodass im Wesentlichen keiner von uns Recht hat.
Femaref
2
Diese Antwort ist nicht nur nicht genau richtig, sondern spricht auch nicht über das eigentliche Problem, was @Longpoke in seiner Antwort ziemlich gut erklärt.
SamB
4

Abgesehen von den bereits veröffentlichten Antworten ist eine Sache die Fähigkeit von Python, Dinge zur Laufzeit zu ändern, die Sie beispielsweise nicht ändern können. Sie können Klassen währenddessen Elementfunktionen hinzufügen. Außerdem macht es die dynamische Natur von Pythons unmöglich zu sagen, welche Art von Parametern an eine Funktion übergeben wird, was wiederum die Optimierung erheblich erschwert.

RPython scheint eine Möglichkeit zu sein, das Optimierungsproblem zu umgehen .

Dennoch wird es wahrscheinlich nicht in der Nähe der Leistung von C für Zahlenverarbeitung und dergleichen sein.

Mattias Nilsson
quelle
Warum sollte RPython keine angemessene Leistung erbringen? Wird es nicht ziemlich direkt in C übersetzt?
SamB
Anscheinend halte ich mich nicht auf dem Laufenden. Es gibt sogar einen Benchmark, bei dem RPython gcc schlägt. Die Zukunft ist schon da :)
Mattias Nilsson
1
C hat keine Klassen. Meinten Sie c ++?
Roman A. Taycher
4

Python wird normalerweise als Skriptsprache implementiert. Das bedeutet, dass es einen Interpreter durchläuft, was bedeutet, dass es Code im laufenden Betrieb in die Maschinensprache übersetzt, anstatt die ausführbare Datei von Anfang an vollständig in Maschinensprache zu haben. Infolgedessen muss es die Kosten für die Übersetzung von Code zusätzlich zur Ausführung bezahlen. Dies gilt auch für CPython, obwohl es zu Bytecode kompiliert wird, der näher an der Maschinensprache liegt und daher schneller übersetzt werden kann. Mit Python kommen auch einige sehr nützliche Laufzeitfunktionen wie die dynamische Typisierung, aber solche Dinge können normalerweise nicht einmal auf den effizientesten Implementierungen ohne hohe Laufzeitkosten implementiert werden.

Wenn Sie sehr prozessorintensive Arbeiten wie das Schreiben von Shadern ausführen, ist Python nicht selten etwa 200-mal langsamer als C ++. Wenn Sie CPython verwenden, kann diese Zeit halbiert werden, aber es ist noch lange nicht so schnell. Mit all diesen Kleinigkeiten ist ein Preis verbunden. Es gibt viele Benchmarks, die dies zeigen, und hier ist eine besonders gute. Wie auf der Titelseite zugegeben, sind die Benchmarks fehlerhaft. Sie werden alle von Benutzern eingereicht, die ihr Bestes geben, um effizienten Code in der Sprache ihrer Wahl zu schreiben, aber es gibt Ihnen eine gute allgemeine Vorstellung.

Ich empfehle Ihnen, beide zu mischen, wenn Sie sich Gedanken über Effizienz machen: Dann können Sie das Beste aus beiden Welten herausholen. Ich bin in erster Linie ein C ++ - Programmierer, aber ich denke, viele Leute neigen dazu, zu viel von dem alltäglichen Code auf hoher Ebene in C ++ zu codieren, wenn dies nur ein Ärgernis ist (Kompilierungszeiten als nur ein Beispiel). Das Mischen einer Skriptsprache mit einer effizienten Sprache wie C / C ++, die näher am Metall liegt, ist wirklich der richtige Weg, um die Effizienz (Produktivität) des Programmierers mit der Effizienz der Verarbeitung in Einklang zu bringen.

stinky472
quelle
Nach Ihrer Definition ist Java auch eine Skriptsprache? Beide Sprachen haben eine Art Bytecode, der in einer virtuellen Maschine ausgeführt wird. Der einzige Unterschied besteht darin, dass Python bei Bedarf im laufenden Betrieb kompiliert wird, was Java normalerweise nicht tut.
Mattias Nilsson
@ Mattias: Nein; Während Sie richtig sind, dass beide Bytecode verwenden, kompiliert Java den Bytecode vor der Ausführung in die native Maschinensprache (entweder im Voraus oder mit einem JIT-Compiler). In einigen Fällen ist Java-Bytecode die native Maschinensprache bestimmter Mikroprozessoren. CPython hingegen ist ein strikter Bytecode- Interpreter . Die gesamte Übersetzungsarbeit wird im laufenden Betrieb ausgeführt, weshalb sie häufig etwa doppelt so schnell ist wie andere Python-Implementierungen, aber immer noch nicht annähernd so schnell wie Java.
stinky472
1
Außerdem kompiliert CPython nicht im laufenden Betrieb, sondern interpretiert Bytecode im laufenden Betrieb. Typische Implementierungen übersetzen denselben Bytecode immer wieder neu, beispielsweise wenn Sie eine Schleife haben. Aus diesem Grund wird es immer noch als Bytecode-Interpreter und nicht als Compiler betrachtet. CPython kompiliert .py-Dateien im laufenden Betrieb zu .pyc (Python zu Bytecode), aber das ist eine ganz andere Sache. pyc ist nur Code, der für den Interpreter leichter zu lesen und zu übersetzen ist, aber dennoch interpretiert wird. Der Java-Ansatz ist eher ein Hybrid und liegt nicht nur am Bytecode, sondern auch daran, was er damit macht.
stinky472
Okay, wir beschäftigen uns mit Fragen, wie Sie Wörter definieren. Demnach wird Java interpretiert (oder war) java.sun.com/docs/overviews/java/java-overview-1.html Aber ja, Sie haben einen Punkt darüber, dass Python-Code nicht in nativen Maschinencode wie Java übersetzt wird. Es sei denn, Sie verwenden psyco mit CPython, das Maschinencode generiert. Oder es sei denn, Sie führen interpretierten Java-Bytecode aus, was ebenfalls möglich ist. Das bedeutet natürlich, dass Sie nichts über eine bestimmte Sprache sagen können, ohne auch anzugeben, wie das Programm ausgeführt wird.
Mattias Nilsson
1
@igouy Ja, aber wenn wir so pedantisch werden, gibt es nichts, was Python langsamer macht als C. Wenn sich jemand genug Mühe geben würde, könnte er möglicherweise etwas Vergleichbares in der Leistung finden, aber das passiert normalerweise nicht . Wenn Sie eine Sprache haben, die dynamisch mit Mechanismen typisiert ist, die nur zur Laufzeit implementiert werden können, wie z. B. Introspektion, entstehen Laufzeitkosten, und selbst die besten Implementierer konnten diese Kosten nicht völlig vernachlässigbar machen. Vielleicht finden sie eines Tages einen revolutionären neuen Weg.
stinky472
4

Der Vergleich von C / C ++ mit Python ist kein fairer Vergleich. Als würde man einen F1-Rennwagen mit einem Nutzfahrzeug vergleichen.

Überraschend ist, wie schnell Python im Vergleich zu anderen dynamischen Sprachen ist. Während die Methodik oft als fehlerhaft angesehen wird, sehen Sie sich das Computersprachen-Benchmark-Spiel an, um die relative Sprachgeschwindigkeit bei ähnlichen Algorithmen zu ermitteln.

Der Vergleich mit Perl, Ruby und C # ist fairer.

dawg
quelle
3
Ich bevorzuge die Metapher eines Lamborghini, der 5 Blocks entfernt arbeitet (nicht speichersichere Sprachen), während eine Straßenbahn Geschwindigkeitsbegrenzungen einhält (speichersichere Sprachen). :)
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
C # ist übrigens statisch typisiert, obwohl es optionale dynamische Typen hat.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
5
C scheint mir eher ein Raketenauto zu sein - großartig, wenn Sie in einer geraden Linie fahren möchten und es nichts gibt, gegen das Sie in der Nähe stoßen könnten, sonst nicht so sehr!
SamB
@drewk - Sie scheinen den Titel für diese Website nicht einmal richtig gelesen zu haben.
igouy
@drewk - "oft als fehlerhaft angesehen" zeigen einige Beweise für diese Anspielung.
igouy
2

C und C ++ werden zu nativem Code kompiliert, dh sie werden direkt auf der CPU ausgeführt. Python ist eine interpretierte Sprache, was bedeutet, dass der von Ihnen geschriebene Python-Code viele, viele Abstraktionsstufen durchlaufen muss, bevor er zu ausführbarem Maschinencode werden kann.

Hündchen
quelle
In einigen Fällen ist es möglich , Python nach C ++ zu kompilieren , sodass es manchmal genauso schnell ist wie nativer Code.
Anderson Green
-5

Python wird interpretiert. Die Sprache wird nicht eingehalten und nicht mit der CPU-Hardware kombiniert

Aber ich habe eine Lösung, um Python als schnellere Programmiersprache zu erhöhen

1.Use python3 for run and code python command like Ubuntu or any Linux distro use python3 main.py and update regularly your python so you python3 framework modules and libraries i will suggest use pip 3.

2.Use [Numba][1] python framework with JIT compiler this framework use for data visualization but you can use for any program this framework use GPU acceleration of your program.

3.Use [Profiler optimizing][1] so this use for see with function or syntax for bit longer or faster also have use full to change syntax as a faster for python its very god and work full so this give a with function or syntax using much more time execution of code.

4.Use multi threading so making multiprocessing of program for python so use CPU cores and threads so this make your code much more faster.

5.Using C,C#,C++ increasing python much more faster i think its called parallel programing use like a [cpython][1] .

6.Debug your code for test your code to make not bug in your code so then you will get little bit your code faster also have one more thing Application logging is for debugging code.

and them some low things that makes your code faster:

 1.Know the basic data structures for using good syntax use make best code.

 2.make a best code have Reduce memory footprinting.

 3.Use builtin functions and libraries.

 4.Move calculations outside the loop.

 5.keep your code base small.

Wenn Sie dieses Ding verwenden, erhalten Sie Ihren Code viel schneller. Ja, wenn Sie dieses Python verwenden, ist dies keine langsame Programmiersprache

Vishawnath Kokare
quelle
1
Willkommen bei SO. Ihre Punkte zur Beschleunigung von Python sind möglicherweise gültig, beantworten jedoch nicht die Frage des OP: "Warum sind Python-Programme häufig langsamer als das in C oder C ++ geschriebene äquivalente Programm?"
RTX13