Diese Implementierung ist auf meinem System schneller als jede Ihrer beiden Funktionen und noch kompakter.
%Vor%Danke an @JBernardo für die vorgeschlagene Verbesserung.
In der neueren Syntax ist str.format
geeigneter:
Dies erzeugt die weitgehend gleiche Ausgabe, obwohl sie jedes Objekt mit einer __str__
-Methode akzeptieren kann, so dass zwei Listen von Ganzzahlen hier immer noch funktionieren könnten.
Diese beiden Lösungen machen sehr verschiedene Dinge. Die erste Schleife wird geschachtelt , dann werden Indizes mit list.index
berechnet, was eine doppelt verschachtelte for-Schleife ergibt und was Sie sich als 125.000.000 Operationen vorstellen können. Die zweite iteriert im Lockstep, macht 500 Paare, ohne 250000 Operationen auszuführen. Kein Wunder, dass sie so anders sind!
Kennen Sie die Big O-Notation , um die Komplexität von Algorithmen zu beschreiben? Wenn dies der Fall ist, ist die erste Lösung kubisch und die zweite Lösung ist linear . Die Kosten für die Auswahl der ersten über die zweite werden mit alarmierender Geschwindigkeit steigen, wenn a
und b
länger werden, also würde niemand einen solchen Algorithmus verwenden.
Persönlich würde ich fast sicher Code wie
verwenden %Vor% oder wenn ich mir über die Größe von a
und b
keine Sorgen mache und nur schnell schreibe, würde ich zip
anstelle von itertools.izip
verwenden. Dieser Code hat mehrere Vorteile
Es ist linear. Obwohl vorzeitige Optimierung ein großes Problem ist, ist es am besten, nicht einen Algorithmus mit einer unnötig schlechten asymptotischen Leistung zu verwenden.
Es ist einfach und idiomatisch. Ich sehe andere Leute, die diesen Code häufig schreiben.
Es ist speichereffizient. Durch die Verwendung eines Generatorausdrucks anstelle eines Listenverständnisses (und itertools.izip
statt zip
) erstelle ich keine unnötigen Listen im Speicher und mache eine O (n) (lineare) Speicheroperation zu einem O (1) (konstante) Speicheroperation.
Was timing betrifft, um die schnellste Lösung zu finden, wäre dies mit ziemlicher Sicherheit ein Beispiel für vorzeitige Optimierung. Um performante Programme zu schreiben, verwenden wir Theorie und Erfahrung, um qualitativ hochwertigen, wartbaren, guten Code zu schreiben. Die Erfahrung zeigt, dass es bestenfalls nutzlos und im schlimmsten Fall kontraproduktiv ist, bei zufälligen Operationen anzuhalten und die Frage zu stellen: "Was ist der beste Weg, um diese bestimmte Operation durchzuführen" und zu versuchen, sie durch Raten oder sogar Testen zu bestimmen.
In Wirklichkeit sind die Programme mit der besten Leistung diejenigen, die mit Code von höchster Qualität und sehr selektiven Optimierungen geschrieben werden. Hochwertiger Code, der die Lesbarkeit und Einfachheit gegenüber Mikrobenchmarks bewertet, ist leichter zu testen, weniger fehleranfällig und besser zu refaktorieren - diese Faktoren sind Schlüssel , um Ihr Programm effektiv zu optimieren. Die Zeit, die Sie damit verbringen, unnötige Bugs zu beheben, komplizierten Code zu verstehen und mit Re-Factoring zu kämpfen, können Sie stattdessen optimieren.
Wenn es darum geht, ein Programm zu optimieren - nachdem es getestet und wahrscheinlich dokumentiert wurde -, geschieht dies nicht an zufälligen Schnipsel, sondern an solchen, die durch tatsächliche Anwendungsfälle und / oder Leistungstests bestimmt sind. Messungen werden von Profilierung . Wenn ein bestimmter Code nur 0,1% der Zeit im Programm benötigt, wird keine Beschleunigung dieses Stückes wirklich gut tun.