Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 117
Sie verpassen Handelsmöglichkeiten:
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Registrierung
Einloggen
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Wenn Sie kein Benutzerkonto haben, registrieren Sie sich
Dies ist die Variante, die ich mir ausgedacht habe:
Es soll die schnellste aller möglichen Varianten sein. Alle Berechnungen werden mit Konstanten durchgeführt, d.h. sie werden während der Kompilierung berechnet. So reduziert sich alles auf nur 6 aufeinanderfolgende Vergleiche und nichts weiter. Allerdings arbeitet diese Variante langsamer als die vorherige. Ich kann nicht verstehen, was der Grund dafür ist.
Dies ist die Variante, die ich mir ausgedacht habe:
Im Prinzip ist dies die schnellste aller möglichen Varianten. Alle Berechnungen werden mit Konstanten durchgeführt, d.h. sie werden während der Kompilierung berechnet. So wird alles auf nur 6 aufeinanderfolgende Vergleiche reduziert, und nichts mehr. Allerdings arbeitet diese Variante langsamer als die vorherige. Ich kann nicht verstehen, was der Grund dafür ist.
Die Division durch zwei verlangsamt es? Ich vermute, dass die berechneten Konstanten - sofort berechnet werden müssen (in diesem Fall - und die Verschiebung in der Definition - muss auch durch eine Konstante ersetzt werden).
Außerdem ist "question" ein ziemlich umstrittener Operator, wie ich weiß. Vor zwanzig Jahren wurde er in C++ geprüft und manchmal erzeugt "question" viel längeren Code als der übliche if-Operator. Vielleicht ist es hier auch so?
Und ich würde den Rückgabecode uint machen - was, wenn es einige Prüfungen bei der Konvertierung von Werten mit und ohne Vorzeichen gibt?
Ich habe noch keine Gelegenheit gehabt, manuell zu experimentieren - die CPU ist stark überlastet... Selbst Text wird "langsam" getippt...
Das Dividieren durch zwei verlangsamt die ? Ich vermute, dass die berechneten Konstanten - sofort berechnet werden müssen (in diesem Fall - und die Verschiebung in der Definition - muss auch durch eine Konstante ersetzt werden).
Auch - "Frage" - wie ich weiß, ist es ein ziemlich umstrittener Operator ...
Ich vermute, dass der resultierende Ausdruck zu lang ist, so dass der Compiler ihn nicht bis zum Ende optimiert hat.
Aber ich habe die Tests mit Optimize=0 durchgeführt, während bei aktivierter Optimierung alles gut lief - die zweite Variante war eineinhalb Mal schneller. Bingo!
Wenn die Optimierung deaktiviert ist, ist die zweite Option bei kleinen Werten etwas langsamer, aber bei größeren Werten etwas schneller. Kurz gesagt, die zweite Option ist definitiv besser.
Dies ist die Variante, die ich mir ausgedacht habe:
Dies ist angeblich die schnellste aller möglichen Varianten. Alle Berechnungen werden mit Konstanten durchgeführt, d.h. sie werden während der Kompilierung berechnet. So reduziert sich alles auf nur 6 aufeinanderfolgende Vergleiche und nichts mehr. Allerdings arbeitet diese Variante langsamer als die vorherige. Ich kann den Grund dafür nicht verstehen.
Das ist richtig - Ihre Variante ist die schnellste.
Es ist nur so, dass der Test untätig ist. Programmierer vergessen sehr oft einen wichtigen Punkt beim Testen der Leistung: Wenn ein berechneter Wert nirgendwo verwendet wird, führt der Compiler die Berechnung einfach nicht aus.
Das macht Sinn, was soll das bringen? Es ist wie in einer Quantensuperposition. Warum sollte es den Mond geben, wenn ihn niemand anschaut? "Gibt es den Mond, nur weil eine Maus ihn anschaut?" (Albert Einstein). :))
Diese Version des Tests mit der Berechnung der Prüfsumme und dem Ausdruck wäre also korrekter:
Ergebnis:
Und der zweite Platz ist immer noch _FastLog2, nicht log2 :))Es ist nur ein Test im Leerlauf. Ein wichtiger Punkt wird bei Leistungstests oft vergessen: Wenn der berechnete Wert nirgendwo verwendet wird, führt der Compiler die Berechnung einfach nicht durch.
Das macht Sinn, was soll das bringen? Es ist wie in einer Quantensuperposition. Warum sollte es den Mond geben, wenn ihn niemand anschaut? "Gibt es den Mond, nur weil eine Maus ihn anschaut?" (Albert Einstein). :))
Diese Version des Tests mit der Prüfsummenberechnung und dem Ausdruck wird also korrekter sein:
Ihr Code ist unübersichtlich. Die Variablen, die im Define verwendet werden, befinden sich am anderen Ende des Programmcodes - es ist unpraktisch, ein solches Chaos zu sortieren. Aber das ist nicht der Punkt. Der Punkt ist, dass die Ergebnisse Ihrer Tests nicht als zuverlässig angesehen werden können, weil der Compiler den Algorithmus der Werte, die der Funktion übergeben werden, im Voraus kennt. Also optimiert er Ihre Tests. Sie sollten mit Zufallszahlen rechnen .
Übrigens, warum haben Sie srand in Ihrem Code? Als ich es sah, dachte ich zuerst, dass Sie random verwenden, aber das ist nicht der Fall.
Hier ist mein Code:
Ihr Code ist verwirrend. Die Variablen, die im Define verwendet werden, befinden sich am anderen Ende des Programmcodes - es ist unbequem, ein solches Chaos zu sortieren. Aber das ist nicht der Punkt, der Punkt ist, dass Ihre Testergebnisse nicht als zuverlässig angesehen werden können, weil der Compiler den Algorithmus der Werte, die der Funktion übergeben werden, im Voraus kennt. Deshalb optimiert er Ihre Tests. Sie sollten mit Zufallszahlen rechnen .
Übrigens, warum haben Sie srand in Ihrem Code? Als ich es sah, dachte ich zuerst, dass Sie random verwenden, aber das ist nicht der Fall.
Hier ist mein Code:
der Code ist nicht von mir. Ich habe es gerade optimiert und rand entfernt, um die gleichen Prüfsummen zu überprüfen und die relativ teure Funktion rand aus der Schleife zu entfernen, aber ich habe einfach vergessen, srand zu entfernen.
Ich gebe Rand zurück. Sie haben Recht - der Compiler optimiert die Schleife für die Summe der Logarithmen von aufeinanderfolgenden Werten. Ich bin allerdings überrascht. Ich verstehe nicht, wie sie das macht. Vielleicht gibt es etwas, das wir nicht berücksichtigen.
Ergebnis:
Der aktuelle Gewinner ist _FastLog2
Ergebnis:
Aktueller Gewinner _FastLog2
Ich frage mich, wie Sie überall die gleiche Prüfsumme erhalten haben, wenn die Werte zufällig sind.
Ich frage mich, wie man überall die gleiche Prüfsumme erhält, wenn die Werte zufällig sind.
srand(45) für alle Funktionen
Ich habe es zuerst so gemacht, aber ich habe unterschiedliche Prüfsummen erhalten, weil ich nicht berücksichtigt habe, dass rand()*rand() 0 sein kann, was die Prüfsumme zerstört. Jetzt habe ich eine hinzugefügt, um von der Null wegzukommen.
srand(45) für alle Funktionen
Ich habe zunächst dasselbe getan, aber unterschiedliche Prüfsummen erhalten, weil ich nicht berücksichtigt habe, dass rand()*rand() 0 sein kann, was die Prüfsumme bricht. Jetzt habe ich eine hinzugefügt, um von der Null wegzukommen.
Und warum braucht man die gleiche Prüfsumme, wenn es um Geschwindigkeitsmessungen geht? Der Sinn der Summe ist in diesem Fall einfach, den Compiler daran zu hindern, den Code zu kürzen, das ist alles. Und indem man srand(45) macht, kann man den Test wieder optimieren.
Apropos Null: FastLog2 prüft nicht auf Null, was ihm einen Vorsprung verschafft. Aber es ist immer noch eineinhalb bis zwei Mal langsamer als log2, wenn es richtig getestet wurde).
Und warum brauchen Sie die gleiche Prüfsumme, wenn es um Geschwindigkeitsmessungen geht? Der Sinn der Summe ist in diesem Fall einfach, den Compiler daran zu hindern, den Code zu kürzen, das ist alles. Und mit srand(45) können Sie den Test wiederum optimieren.
Sie überschätzen hier die Fähigkeiten des Compilers. Entfernen Sie srand(45) - die Prüfsummen werden unterschiedlich sein, aber das Geschwindigkeitsergebnis bleibt das gleiche.
Außerdem habe ich mich von der Tatsache leiten lassen, dass die Berechnungen aus Gründen der Reinheit des Experiments gleich waren, weil ich nicht auf alle Funktionen im Detail eingegangen bin. Manchmal kann der Wert eines Funktionsparameters den Zeitpunkt der Ausführung beeinflussen.
Umso wichtiger ist es, die Korrektheit der Algorithmen zu überprüfen.