Je souhaite partager avec les programmeurs une découverte inattendue, simple et utile.
Les fonctions d'arrondi :
se sont avérés très lents. Pour accélérer le processus d'arrondi de 4 à 5 fois (selon mes tests dans MQL5), vous pouvez remplacer ces fonctions par une alternative simple :
Comme ces fonctions sont souvent utilisées dans des boucles importantes et imbriquées, le gain de performance peut être très important.
Probablement, le fait d'appeler une fonction prend beaucoup de temps (stockage de différentes données, adresses, etc.). Et dans ce cas, vous pouvez vous passer des fonctions.
Fichier script avec test de performance joint.
Seulement moi avec cette ligne
y=round(x); -> y=(int)(x+0.5);
Je ne suis pas d'accord avec cette ligne. Selon les règles des mathématiques, si la partie fractionnaire est inférieure à 0,5, l'arrondi se fait à la partie inférieure. Mais si vous ajoutez 0,5 à 45,27, il est arrondi à la hausse.
Seulement, je ne suis pas d'accord avec cette ligne.
Je ne suis pas d'accord. Selon les règles des mathématiques, si la partie fractionnaire est inférieure à 0,5, elle est arrondie au chiffre inférieur. Mais si vous ajoutez 0,5 à 45,27, il est arrondi à la hausse.
#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)," микросекунд"); } //+------------------------------------------------------------------+
Seulement, je ne suis pas d'accord avec cette ligne.
Je ne suis pas d'accord. Selon les règles des mathématiques, si la partie fractionnaire est inférieure à 0,5, elle est arrondie au chiffre inférieur. Mais si vous ajoutez 0,5 à 45,27, c'est arrondi vers le haut.
Vous êtes confus. J'ai volontairement inséré un code de vérification dans l'exemple :
for(int i=0;i<10000000;i++) { if ((int)(x+0.5)!=(int)round(x)) Print("ой...",x); x+=0.27; }
Si je me trompais, l'opérateurPrint("oops...",x) serait exécuté ;
Essayez-le - c'est bon.
Je suis le seul à avoir cette phrase.
ne sont pas d'accord. Selon les règles des mathématiques, si la partie fractionnaire est inférieure à 0,5, elle est arrondie au chiffre inférieur. Mais si vous ajoutez 0,5 à 45,27, le résultat est arrondi à la hausse.
Que diriez-vous de le prendre et de le vérifier ? ))) Comment int(45.27 + 0.5) donnerait-il 46 ? Les mêmes 45 resteront.
Je ne parlais pas de vitesse.
Vous devez être confus. J'ai volontairement inséré un code de contrôle dans l'exemple :
si je me trompais, alors l'instructionPrint("oops...",x) serait exécutée ;
Essayez-le - c'est bon.
Mais il est tout de même intéressant de constater que la vitesse change si le tableaun'est pas rempli de donnéesau préalable.
#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)," микросекунд"); } //+------------------------------------------------------------------+
et rempli
#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)," микросекунд"); } //+------------------------------------------------------------------+
Que diriez-vous d'un test ? ))) Comment int(45.27 + 0.5) donnerait-il 46 ? Les mêmes 45 resteront.
Je suis d'accord, j'ai perdu le fil de mes pensées. Je retire ce que j'ai dit...
Mais il est tout de même intéressant de constater que la vitesse change si le tableaun'est pas rempli de donnéesau préalable.
et le remplir
y0[i]+=0; // !!!!!!!!!!!!!!
Je trouve "#define" plus pratique
#define _floor(x) (int)((x)) #define _ceil(x) (int)((x)+(1)) #define _round(x) (int)((x)+(0.5))
Pourquoi ne pas faire un lancer vers le long ? Bien qu'il puisse aussi être bondé, mais il est beaucoup plus facile d'y entrer.
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation
Je souhaite partager avec les programmeurs une découverte inattendue, simple et utile.
Les fonctions d'arrondi :
se sont avérés très lents. Pour accélérer le processus d'arrondi de 4 à 5 fois (selon mes tests dans MQL5), vous pouvez remplacer ces fonctions par une alternative simple :
Comme ces fonctions sont souvent utilisées dans des boucles importantes et imbriquées, le gain de performance peut être très important.
Probablement, le fait d'appeler une fonction prend beaucoup de temps (stockage de différentes données, adresses, etc.). Et dans ce cas, vous pouvez vous passer des fonctions.
Fichier du script avec test de performance joint.