Alternative Implementierungen von Standardfunktionen/-ansätzen - Seite 10

 
pavlick_:
)). Dies mag nur in persönlichen Handwerksbetrieben mit genauer Kenntnis des Wertebereichs einen Platz haben, aber nicht in der Standardbibliothek. Die eingebauten Funktionen werden nicht von Dummköpfen geschrieben, halten Sie sich nicht für die Klügsten. Hier ist ein Freund, der auch undefiniertes und nicht spezifiziertes Verhalten schreibt und dann überrascht ist, dass es so nicht funktioniert https://www.linux.org.ru/forum/development/14422428#comments. All diese Einsparungen von mehreren Nanosekunden werden im realen Algorithmus (nicht in der nackten Schleife) nicht einmal sichtbar sein.

Erst jetzt habe ich mitbekommen, was Sie gesagt haben.
Ich nehme zurück, dass Sie nicht auf dem Laufenden sind. Ich bitte um Entschuldigung.
Ja, Sie können diese Variante unter der Voraussetzung verwenden, dass die Zahl double im Bereich von -9007199254740992 bis 9007199254740992 (2 hoch 53 (Anzahl der Bits in der Mantisse)) liegt.

 
Renat Fatkhullin:
Überlegen Sie sich, was Sie außerhalb des ganzzahligen Bereichs erhalten werden.

Wie wäre es damit?

double Ceil (double x) { return double((x>9007199254740992 || x<-9007199254740992 )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}

Ergebnis:

2018.08.26 10:49:23.552 TestRound (Crypto.ALT,M10)      Время цикла без округления = 1.317 наносекунд, сумма = 115583114403605978808320.00000000
2018.08.26 10:49:23.556 TestRound (Crypto.ALT,M10)      Время выполнения функции ceil =  2.129 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.557 TestRound (Crypto.ALT,M10)      Время выполнения функции Ceil =  0.100 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.560 TestRound (Crypto.ALT,M10)      Время выполнения функции floor = 1.299 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.561 TestRound (Crypto.ALT,M10)      Время выполнения функции Floor = 0.120 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.564 TestRound (Crypto.ALT,M10)      Время выполнения функции round = 1.787 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.566 TestRound (Crypto.ALT,M10)      Время выполнения функции Round = 0.106 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 10:49:23.566 TestRound (Crypto.ALT,M10)      Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать

der Test scheint vollständige Identität zu zeigen.

Die Geschwindigkeit der alternativen Lösung in diesem Fall, bei der eine Bereichsprüfung durchgeführt wird, ist jedoch um etwa das Zweifache höher (statt 3-8), allerdings nur, wenn die Zahl double im Bereichvon -9007199254740992 bis 9007199254740992 liegt.Außerhalb dieses Bereichs ist sie jedoch viel höher.

Dateien:
TestRound.mq5  9 kb
 
Nikolai Semko:


der Test scheint vollständige Identität zu zeigen.

Diese Variante berücksichtigt jedoch nicht den Überlauf der Eingangsvariablenvom Typ double, wenn sie die Werte nan, snan annimmt.

Wenn dies berücksichtigt werden muss, können Sie eine weitere Prüfung hinzufügen, aber dennoch wird diese Variante schneller arbeiten als die ursprüngliche Funktion

double Ceil (double x) { return double((!MathIsValidNumber(x) || x>9007199254740992 || x<-9007199254740992 )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((!MathIsValidNumber(x) || x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((!MathIsValidNumber(x) || x>9007199254740992 || x<-9007199254740992 )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}
 
Nikolai Semko:

Erstellen Sie einen EA für einen Tester/Optimierer. Deshalb ist Schnelligkeit in der Praxis wichtig.

 
fxsaber:

Erstellen Sie einen EA für einen Tester/Optimierer. Deshalb ist Geschwindigkeit in der Praxis so wichtig.

Wie viele Leute wissen, mache ich auch glatte Grafiken. Für die Glättung von Grafiken und die Arbeit mit jedem einzelnen Pixel werden Rundungsfunktionen aktiv eingesetzt.

Früher konnte ich mir nicht einmal vorstellen, dass die Rundungsfunktion langsamer ist als die Extraktion der Quadratwurzel aus Double.
Aus diesem Grund habe ich mir angewöhnt, diese Nanosekunden zu unterdrücken. Denn diese Nanosekunden auf der geglätteten Grafik können bei jedem Bild zu Millisekunden werden, und ein Bild kann sich alle 33 Millisekunden ändern.

 
Nikolai Semko:

Wie viele wissen, beschäftige ich mich auch mit Anti-Aliasing-Grafiken. Für eine flüssige Grafik und die Arbeit mit jedem Pixel werden die Rundungsfunktionen aktiv genutzt.
Aus diesem Grund habe ich mich bemüht, diese Nanosekunden zu glätten. Denn diese Nanosekunden auf den geglätteten Grafiken können bei jedem Bild zu Millisekunden werden, und ein Bild kann sich alle 33 Millisekunden ändern.

Dies ist natürlich für die Grafik wichtig. Deshalb gibt es dort schon seit langem algorithmische Optimierungen für fast alle gängigen Aufgaben.

 
fxsaber:

Dies ist natürlich für die Grafik wichtig. Deshalb gibt es dort schon seit langem algorithmische Optimierungen für fast alle gängigen Aufgaben.

Sie irren sich. Das Feld ist immer noch nicht gepflügt, und was gepflügt ist, ist geschlossen. Und in MQL umso mehr. CCanvas Klasse ist sehr weit von Optimalität und es gibt fast keine Antialiasing und was es von Antialiasing ist unbefriedigend.

 

Warum verwenden Sie nicht LONG_MAX/MIN? Das würde irgendwie schöner aussehen. Es sieht gut aus, finde ich. Ich lief Ihre Tests mit gcc (mit min Änderung, natürlich, sehr alten Compiler 5.4.0, was ich zur Hand hatte):

1. Kompilieren mit -O3.

Время цикла без округления = 0.001099185 секунд, сумма = 1.15583114 e+23
Время выполнения функции ceil =  0.004310106 секунд, сумма = 1.15583114 e+23
Время выполнения функции Ceil =  0.001912712 секунд, сумма = 1.15583114 e+23
Время выполнения функции floor =  0.005283493 секунд, сумма = 1.15583114 e+23
Время выполнения функции Floor =  0.002031304 секунд, сумма = 1.15583114 e+23
Время выполнения функции round =  0.005308409 секунд, сумма = 1.15583114 e+23
Время выполнения функции Round =  0.002344382 секунд, сумма = 1.15583114 e+23

2. Kompilieren mit -Ofast

Время цикла без округления = 0.000552652 секунд, сумма = 1.15583114 e+23
Время выполнения функции ceil =  0.001720999 секунд, сумма = 1.15583114 e+23
Время выполнения функции Ceil =  0.00189282 секунд, сумма = 1.15583114 e+23
Время выполнения функции floor =  0.001430063 секунд, сумма = 1.15583114 e+23
Время выполнения функции Floor =  0.001979336 секунд, сумма = 1.15583114 e+23
Время выполнения функции round =  0.001698521 секунд, сумма = 1.15583114 e+23
Время выполнения функции Round =  0.001944874 секунд, сумма = 1.15583114 e+23

Ihr Code hat ein Problem mit der Zeitberechnung - die Ausgabe erfolgt in Millisekunden (nicht in Nanosekunden), und ich verstehe immer noch nicht, warum Sie minus t0 benötigen.

Print("Время выполнения функции ceil =  "+DoubleToString((double)(GetMicrosecondCount()-t-t0)/1000,3)+" наносекунд, Контрольная сумма = "+string(s));
 
Nikolai Semko:

Falsch. Es gibt noch ein ungepflügtes Feld, und was gepflügt ist, ist geschlossen.

Ich habe von der weltweiten Erfahrung gesprochen. Schauen Sie sich die Algorithmen in den thematischen Foren an, in denen Diagrammdemos erstellt werden. Die Leute teilen ihre schnellen Algorithmen.

 
fxsaber:

Ich habe von der weltweiten Erfahrung gesprochen. Suchen Sie nach Algorithmen in den thematischen Foren, in denen Graph-Demos erstellt werden. Die Menschen tauschen schnelle Algorithmen aus.

Bitte senden Sie mir den Link.