Ich möchte eine unerwartete, einfache und nützliche Erkenntnis mit den Programmierern teilen.
Die Rundungsfunktionen:
Sie haben sich als sehr langsam erwiesen. Um den Rundungsprozess um das 4-5fache zu beschleunigen (nach meinen Tests in MQL5), können Sie diese Funktionen durch eine einfache Alternative ersetzen:
Da diese Funktionen häufig in großen und verschachtelten Schleifen verwendet werden, kann der Leistungsgewinn beträchtlich sein.
Wahrscheinlich ist der Aufruf einer Funktion recht zeitaufwendig (Speicherung verschiedener Daten, Adressen usw.). Und in diesem Fall können Sie auf Funktionen verzichten.
Skriptdatei mit Leistungstest im Anhang.
Nur ich mit dieser Zeile
y=round(x); -> y=(int)(x+0.5);
Ich bin mit diesem Satz nicht einverstanden. Nach den Regeln der Mathematik wird, wenn der Bruchteil kleiner als 0,5 ist, auf die niedrigere Seite gerundet. Wenn Sie jedoch 0,5 zu 45,27 addieren, wird der Wert nach oben gerundet.
Nur bin ich mit diesem Satz nicht einverstanden.
Dem stimme ich nicht zu. Nach den Regeln der Mathematik wird der Bruchteil, der kleiner als 0,5 ist, abgerundet. Wenn Sie jedoch 0,5 zu 45,27 addieren, wird der Wert nach oben gerundet.
#define MUL(x) ((x)+(0.5)) //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { ulong t0,t1,t2,t3; int y0[],y1[],y2[]; ArrayResize(y0,10000000); ArrayResize(y1,10000000); ArrayResize(y2,10000000); double x=1.45; for(int i=0;i<10000000;i++) { if ((int)(x+0.5)!=(int)round(x)) Print("ой...",x); x+=0.27; y0[i]+=0; y1[i]+=0; y2[i]+=0; } Print("y0[]: ",y0[9999999]," / y1[]: ",y1[9999999]," / y2[]: ",y2[9999999]); x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y0[i]=(int)MathRound(x); x+=0.27; } t1=GetMicrosecondCount()-t0; Print("y0[]: ",y0[9999999]); x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y1[i]=(int)(x+0.5); x+=0.27; } t2=GetMicrosecondCount()-t0; Print("y1[]: ",y1[9999999]); x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y2[i]=(int)MUL(x); x+=0.27; } t3=GetMicrosecondCount()-t0; Print("y2[]: ",y2[9999999]); Print("Цикл округления 10 000 000 раз: (round) = ",IntegerToString(t1)," альтернатива с (int) = ",IntegerToString(t2)," альтернатива с (#define) = ",IntegerToString(t3)," микросекунд"); } //+------------------------------------------------------------------+
Nur bin ich mit diesem Satz nicht einverstanden.
Dem stimme ich nicht zu. Nach den Regeln der Mathematik wird der Bruchteil, der kleiner als 0,5 ist, abgerundet. Aber wenn man 0,5 zu 45,27 addiert, wird aufgerundet.
Sie sind verwirrt. Ich habe absichtlich einen Verifizierungscode in das Beispiel eingefügt:
for(int i=0;i<10000000;i++) { if ((int)(x+0.5)!=(int)round(x)) Print("ой...",x); x+=0.27; }
Wenn ich mich geirrt hätte, wäre der OperatorPrint("oops...",x) ausgeführt worden;
Probieren Sie es aus - es ist in Ordnung.
Ich bin der Einzige, der diesen Satz sagt.
nicht zustimmen. Nach den Regeln der Mathematik wird der Bruchteil, der kleiner als 0,5 ist, abgerundet. Wenn man aber 0,5 zu 45,27 addiert, wird der Wert nach oben gerundet.
Wie wär's, wenn Sie es mitnehmen und ausprobieren? ))) Wie würde int(45,27 + 0,5) 46 ergeben? Die gleichen 45 werden bleiben.
Ich habe nicht von der Geschwindigkeit gesprochen.
Sie müssen verwirrt sein. Ich habe absichtlich einen Prüfcode in das Beispiel eingefügt:
wenn ich mich geirrt hätte, würde die AnweisungPrint("oops...",x) ausgeführt werden;
Probieren Sie es aus - es ist in Ordnung.
Dennoch ist es interessant, dass sich die Geschwindigkeit ändert, wenn das Arraynichtvorhermit Daten gefüllt wird
#define _round(x) (int)((x)+(0.5)) //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { ulong t0,t1,t2; int y0[],y1[]; ArrayResize(y0,10000000); double x=1.45; for(int i=0;i<10000000;i++) { if ((int)(x+0.5)!=(int)round(x)) Print("ой...",x); x+=0.27; y0[i]+=0; // !!!!!!!!!!!!!! } x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y0[i]=(int)(x+0.5); x+=0.27; } t1=GetMicrosecondCount()-t0; x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y0[i]=_round(x); x+=0.27; } t2=GetMicrosecondCount()-t0; Print("Цикл округления 10 000 000 раз: с (int) = ",IntegerToString(t1)," с (#define) = ",IntegerToString(t2)," микросекунд"); } //+------------------------------------------------------------------+
und gefüllt
#define _round(x) (int)((x)+(0.5)) //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { ulong t0,t1,t2; int y0[],y1[]; ArrayResize(y0,10000000); double x=1.45; for(int i=1;i<10000000;i++) { if ((int)(x+0.5)!=(int)round(x)) Print("ой...",x); x+=0.27; y0[i]+=1; // !!!!!!!!!!!!!! } x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y0[i]=(int)(x+0.5); x+=0.27; } t1=GetMicrosecondCount()-t0; x=1.45; t0=GetMicrosecondCount(); for(int i=0;i<10000000;i++) { y0[i]=_round(x); x+=0.27; } t2=GetMicrosecondCount()-t0; Print("Цикл округления 10 000 000 раз: с (int) = ",IntegerToString(t1)," с (#define) = ",IntegerToString(t2)," микросекунд"); } //+------------------------------------------------------------------+
Wie wäre es, wenn Sie das überprüfen? ))) Wie würde int(45,27 + 0,5) 46 ergeben? Die gleichen 45 werden bleiben.
Ich stimme zu, ich habe meinen Gedankengang verloren. Ich nehme es zurück...
Dennoch ist es interessant, dass sich die Geschwindigkeit ändert, wenn das Arraynichtvorhermit Daten gefüllt wird
und füllen ihn
y0[i]+=0; // !!!!!!!!!!!!!!
Ich finde "#define" praktischer
#define _floor(x) (int)((x)) #define _ceil(x) (int)((x)+(1)) #define _round(x) (int)((x)+(0.5))
Warum wirfst du nicht in die Länge? Obwohl man ihn auch überlaufen lassen kann, ist es viel einfacher, einen Int zu überlaufen.
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Ich möchte eine unerwartete, einfache und nützliche Erkenntnis mit Programmierern teilen.
Die Rundungsfunktionen:
Sie haben sich als sehr langsam erwiesen. Um den Rundungsprozess um das 4-5fache zu beschleunigen (nach meinen Tests in MQL5), können Sie diese Funktionen durch eine einfache Alternative ersetzen:
Da diese Funktionen häufig in großen und verschachtelten Schleifen verwendet werden, kann der Leistungsgewinn beträchtlich sein.
Wahrscheinlich ist der Aufruf einer Funktion recht zeitaufwendig (Speicherung verschiedener Daten, Adressen usw.). Und in diesem Fall können Sie auf Funktionen verzichten.
Datei des Skripts mit Leistungstest im Anhang.