Ich habe mich schon seit einiger Zeit gefragt. Wie der Titel schon sagt, was ist schneller, die eigentliche Funktion oder einfach auf die halbe Potenz zu erhöhen?
AKTUALISIEREN
Dies ist keine Frage der vorzeitigen Optimierung. Dies ist lediglich eine Frage der tatsächlichen Funktionsweise des zugrunde liegenden Codes. Wie funktioniert Python-Code?
Ich habe Guido van Rossum eine E-Mail geschickt, weil ich wirklich die Unterschiede in diesen Methoden wissen wollte.
Meine E-Mail:
Es gibt mindestens drei Möglichkeiten, eine Quadratwurzel in Python zu erstellen: math.sqrt, der Operator '**' und pow (x, .5). Ich bin nur neugierig auf die Unterschiede in der Implementierung von jedem dieser. Was ist besser, wenn es um Effizienz geht?
Seine Antwort:
pow und ** sind äquivalent; math.sqrt funktioniert nicht für komplexe Zahlen und verknüpft mit der Funktion C sqrt (). Welcher schneller ist, weiß ich nicht ...
quelle
math.sqrt
es sich um eine optimierte Routine handelt (wie sie ist) und die Absicht klarer zum Ausdruck bringt, sollte sie immer vorgezogen werdenx**.5
. Es ist keine vorzeitige Optimierung, zu wissen, was Sie schreiben, und die Alternative zu wählen, die schneller ist und mehr Codeklarheit bietet. Wenn ja, müssen Sie gleich gut argumentieren, warum Sie die anderen Alternativen gewählt haben.Antworten:
math.sqrt(x)
ist deutlich schneller alsx**0.5
.Verwenden von Python 3.6.9 ( Notizbuch ).
quelle
Hier sind einige Timings (Python 2.5.2, Windows):
Dieser Test zeigt, dass
x**.5
das etwas schneller ist alssqrt(x)
.Für Python 3.0 ist das Ergebnis das Gegenteil:
math.sqrt(x)
ist immer schneller alsx**.5
auf einem anderen Computer (Ubuntu, Python 2.6 und 3.1):quelle
Wie viele Quadratwurzeln spielen Sie wirklich? Versuchen Sie, eine 3D-Grafik-Engine in Python zu schreiben? Wenn nicht, warum dann mit kryptischem Code über leicht lesbaren Code gehen? Der Zeitunterschied wäre geringer, als irgendjemand in so gut wie jeder Anwendung, die ich vorhersehen könnte, bemerken könnte. Ich möchte Ihre Frage wirklich nicht aufschreiben, aber es scheint, dass Sie mit vorzeitiger Optimierung etwas zu weit gehen.
quelle
In diesen Mikro-Benchmarks
math.sqrt
wird es langsamer sein, da das Nachschlagensqrt
im mathematischen Namespace nur wenig Zeit in Anspruch nimmt . Sie können es mit leicht verbessernSelbst dann, wenn Sie einige Variationen durch die Zeit laufen lassen, zeigen Sie einen leichten (4-5%) Leistungsvorteil für
x**.5
Interessanterweise tun
beschleunigte es noch weiter, bis auf einen Geschwindigkeitsunterschied von 1%, mit sehr geringer statistischer Signifikanz.
Ich werde Kibbee wiederholen und sagen, dass dies wahrscheinlich eine vorzeitige Optimierung ist.
quelle
In Python 2.6 verwendet die
(float).__pow__()
Funktion die C-pow()
Funktion und diemath.sqrt()
Funktionen das C.sqrt()
Funktion.Im glibc-Compiler ist die Implementierung von
pow(x,y)
recht komplex und für verschiedene Ausnahmefälle gut optimiert. Wenn Sie beispielsweise C aufrufen, wirdpow(x,0.5)
einfach diesqrt()
Funktion aufgerufen.Der Unterschied in der Geschwindigkeit der Verwendung
.**
odermath.sqrt
wird durch die Wrapper verursacht, die für die C-Funktionen verwendet werden, und die Geschwindigkeit hängt stark von den auf dem System verwendeten Optimierungsflags / C-Compilern ab.Bearbeiten:
Hier sind die Ergebnisse von Claudius Algorithmus auf meinem Computer. Ich habe unterschiedliche Ergebnisse erhalten:
quelle
Für das, was es wert ist (siehe Jims Antwort). Auf meinem Computer wird Python 2.5 ausgeführt:
quelle
Mit Claudius Code ist auf meinem Computer sogar mit "from math import sqrt" x **. 5 schneller, aber mit psyco.full () sqrt (x) wird es viel schneller, zumindest um 200%
quelle
Höchstwahrscheinlich math.sqrt (x), da es für Quadratwurzeln optimiert ist.
Benchmarks geben Ihnen die Antwort, die Sie suchen.
quelle
Jemand hat die "schnelle Newton-Raphson-Quadratwurzel" aus Quake 3 kommentiert ... Ich habe sie mit ctypes implementiert, aber sie ist im Vergleich zu den nativen Versionen sehr langsam. Ich werde einige Optimierungen und alternative Implementierungen ausprobieren.
Hier ist eine andere Methode, die struct verwendet. Sie ist etwa 3,6-mal schneller als die ctypes-Version, aber immer noch 1/10 der Geschwindigkeit von C.
quelle
Claudius Ergebnisse unterscheiden sich von meinen. Ich verwende Python 2.6 unter Ubuntu auf einem alten P4 2.4Ghz-Computer ... Hier sind meine Ergebnisse:
sqrt ist für mich durchweg schneller ... Sogar Codepad.org scheint JETZT zuzustimmen, dass sqrt im lokalen Kontext schneller ist ( http://codepad.org/6trzcM3j) ). Auf dem Codepad scheint derzeit Python 2.5 ausgeführt zu werden. Vielleicht benutzten sie 2.4 oder älter, als Claudiu das erste Mal antwortete?
Selbst wenn ich math.sqrt (i) anstelle von arg (i) verwende, bekomme ich immer noch bessere Zeiten für sqrt. In diesem Fall dauerte timeit2 () auf meinem Computer zwischen 0,53 und 0,55 Sekunden, was immer noch besser ist als die 0,56-0,60-Zahlen von timeit1.
Ich würde sagen, verwenden Sie in modernem Python math.sqrt und bringen Sie es definitiv in den lokalen Kontext, entweder mit somevar = math.sqrt oder mit aus math import sqrt.
quelle
Die pythonische Sache, für die optimiert werden muss, ist die Lesbarkeit. Dafür denke ich explizite Verwendung der
sqrt
Funktion für am besten. Lassen Sie uns trotzdem die Leistung untersuchen.Ich habe Claudius Code für Python 3 aktualisiert und es auch unmöglich gemacht, die Berechnungen zu optimieren (etwas, das ein guter Python-Compiler in Zukunft tun könnte):
Die Ergebnisse variieren, aber eine Beispielausgabe lautet:
Versuch es selber.
quelle
Das Problem SQRMINSUM, das ich kürzlich gelöst habe, erfordert die wiederholte Berechnung der Quadratwurzel für einen großen Datensatz. Die ältesten 2 Einsendungen in meiner Geschichte , bevor ich andere Optimierungen vorgenommen habe, unterscheiden sich ausschließlich dadurch, dass ** 0,5 durch sqrt () ersetzt wird, wodurch die Laufzeit in PyPy von 3,74 auf 0,51 Sekunden reduziert wird. Dies ist fast das Doppelte der bereits massiven Verbesserung von 400%, die Claudiu gemessen hat.
quelle
Wenn man sich mit Literalen befasst und einen konstanten Wert benötigt, kann die Python-Laufzeit den Wert zur Kompilierungszeit vorberechnen, wenn er mit Operatoren geschrieben wird. In diesem Fall muss nicht jede Version profiliert werden:
quelle
Noch schneller wäre es, wenn Sie in math.py die Funktion "sqrt" in Ihr Programm kopieren würden. Es dauert einige Zeit, bis Ihr Programm math.py gefunden, dann geöffnet, die gesuchte Funktion gefunden und dann wieder in Ihr Programm aufgenommen hat. Wenn diese Funktion trotz der "Such" -Schritte schneller ist, muss die Funktion selbst furchtbar schnell sein. Vermutlich wird sich Ihre Zeit halbieren. Zusammenfassend:
quelle
from math import sqrt
?