Generiert der Compiler den gleichen Code für iter().map().sum()
und iter().fold()
? Am Ende erreichen sie das gleiche Ziel, aber der erste Code würde zweimal durchlaufen, einmal für die map
und einmal für die sum
.
Hier ist ein Beispiel. Welche Version wäre in total
schneller?
Was wären gute Werkzeuge, um die Baugruppe zu betrachten oder zu benchmarken?
Damit sie den gleichen Code generieren können, müssen sie zuerst dasselbe tun . Ihre beiden Beispiele nicht:
%Vor% %Vor%Nehmen wir an, Sie meinten
%Vor%Es gibt ein paar Möglichkeiten zu überprüfen:
Die einfachste Quelle für IR und Assembly ist einer der Spielplätze ( offiziell oder alternative ). Beide verfügen über Schaltflächen zum Anzeigen der Baugruppe oder IR. Sie können auch --emit=llvm-ir
oder --emit=asm
an den Compiler übergeben, um diese Dateien zu generieren.
Stellen Sie sicher, dass die Assembly oder IR im Freigabemodus generiert wird. Das Attribut #[inline(never)]
ist oft nützlich, um Funktionen getrennt zu halten, um sie leichter in der Ausgabe zu finden.
Das Benchmarking ist in der Rust Programmiersprache dokumentiert, so dass es nicht notwendig ist, es zu wiederholen all diese wertvollen Informationen.
Vor Rust 1.14 erzeugen diese nicht die exakte gleiche Baugruppe. Ich würde auf Benchmarking- / Profiling-Daten warten, um zu sehen, ob es einen bedeutungsvollen Einfluss auf die Performance gibt, bevor ich mir Sorgen mache.
Ab Rust 1.14 erzeugen sie dieselbe Baugruppe ! Das ist einer der Gründe, warum ich Rust liebe. Du kannst klaren und idiomatischen Code schreiben und kluge Leute kommen und machen es genauso schnell .
>aber der erste Code würde zweimal durchlaufen, einmal für die
map
und einmal für diesum
.
Das ist falsch, und ich würde gerne wissen, welche Quelle Ihnen das gesagt hat, damit wir es korrigieren und zukünftige Missverständnisse verhindern können. Ein Iterator arbeitet auf Pull-Basis; Ein Element wird gleichzeitig verarbeitet. Die Kernmethode ist next
, was zu einem einzelnen Wert führt, der gerade genug Berechnungen ausführt, um diesen Wert zu erzeugen.
Lassen Sie uns zunächst das Beispiel korrigieren, um das gleiche Ergebnis zu erhalten:
%Vor% Entwickeln wir sie jetzt, beginnend mit fold
. A fold
ist nur eine Schleife und ein Akkumulator, es entspricht grob :
Lassen Sie uns dann mit map
und sum
gehen und die sum
zuerst entpacken, was ungefähr entspricht:
Es ist nur ein einfacher Akku! Und jetzt wollen wir die Ebene map
auspacken (die nur eine Funktion anwendet) und etwas erhalten, das ungefähr entspricht:
Wie Sie sehen können, sind die beiden extrem ähnlich: Sie haben die gleichen Operationen in der gleichen Reihenfolge und haben die gleiche Gesamtkomplexität.
Was ist schneller? Ich habe keine Ahnung. Und ein Mikro-Benchmark mag sowieso nur die halbe Wahrheit sagen: Nur weil etwas in einem Mikro-Benchmark schneller ist, heißt das nicht, dass es in der Mitte von anderem Code schneller ist.
Was ich sagen kann, ist jedoch, dass sie beide eine äquivalente Komplexität haben und sich daher ähnlich verhalten sollten, dh innerhalb eines Faktors voneinander.
Und ich würde persönlich für map
+ sum
gehen, weil es die Absicht deutlicher ausdrückt, während fold
das "Küchenbecken" von Iterator
Methoden ist und daher weit weniger informativ ist.
Tags und Links rust