Quiero compartir con los programadores un hallazgo inesperado, sencillo y útil.
Las funciones de redondeo:
Han demostrado ser muy lentos. Para acelerar el proceso de redondeo entre 4 y 5 veces (según mis pruebas en MQL5), puedes sustituir estas funciones por una alternativa sencilla:
Dado que estas funciones se utilizan a menudo en bucles grandes y anidados, la ganancia de rendimiento puede ser bastante significativa.
Probablemente, el hecho de llamar a una función consume bastante tiempo (almacenamiento de diferentes datos, direcciones, etc.). Y en este caso se puede prescindir de las funciones.
Se adjunta el archivo de script con la prueba de rendimiento.
Sólo yo con esta línea
y=round(x); -> y=(int)(x+0.5);
No estoy de acuerdo con esta línea. Según las reglas de las matemáticas, si la parte fraccionaria es inferior a 0,5, el redondeo se realiza hacia el lado inferior. Pero si se añade 0,5 a 45,27, se redondea hacia el lado más alto.
Sólo que no estoy de acuerdo con esa línea.
No estoy de acuerdo. Según las reglas de las matemáticas, si la parte fraccionaria es inferior a 0,5, se redondea hacia abajo. Pero si se añade 0,5 a 45,27, se redondea hacia el lado más alto.
#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)," микросекунд"); } //+------------------------------------------------------------------+
Sólo que no estoy de acuerdo con esa línea.
No estoy de acuerdo. Según las reglas de las matemáticas, si la parte fraccionaria es inferior a 0,5, se redondea hacia abajo. Pero si añades 0,5 a 45,27, se redondea hacia el lado más alto.
Estás confundido. He insertado a propósito un código de verificación en el ejemplo:
for(int i=0;i<10000000;i++) { if ((int)(x+0.5)!=(int)round(x)) Print("ой...",x); x+=0.27; }
Si me equivocara, se ejecutaría el operadorPrint("oops...",x);
Pruébalo, está bien.
Soy el único con esa línea.
no están de acuerdo. Según las reglas de las matemáticas, si la parte fraccionaria es inferior a 0,5, se redondea hacia abajo. Pero si añades 0,5 a 45,27, se redondea hacia el lado más alto.
¿Qué tal si lo tomas y lo compruebas? ))) ¿Cómo es que int(45,27 + 0,5) da 46? Se mantendrán los mismos 45.
No me refería a la velocidad.
Debes estar confundido. He insertado a propósito un código de verificación en el ejemplo:
si estuviera equivocado, entonces se ejecutaría la sentenciaPrint("oops...",x);
Pruébalo, está bien.
Pero no deja de ser interesante que la velocidad cambie si el arrayno estálleno de datosde antemano
#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)," микросекунд"); } //+------------------------------------------------------------------+
y llenado
#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)," микросекунд"); } //+------------------------------------------------------------------+
¿Qué tal si lo compruebas? ))) ¿Cómo es que int(45,27 + 0,5) da 46? Se mantendrán los mismos 45.
Estoy de acuerdo, he perdido el hilo. Me retracto...
Pero no deja de ser interesante que la velocidad cambie si el arrayno está lleno de datosde antemano
y llenarlo
y0[i]+=0; // !!!!!!!!!!!!!!
Me parece que "#define" es más conveniente
#define _floor(x) (int)((x)) #define _ceil(x) (int)((x)+(1)) #define _round(x) (int)((x)+(0.5))
¿Por qué no lanzas a lo largo? Aunque también se puede desbordar, es mucho más fácil desbordar un Int.

- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso
Quiero compartir con los programadores un hallazgo inesperado, sencillo y útil.
Las funciones de redondeo:
Han demostrado ser muy lentos. Para acelerar el proceso de redondeo entre 4 y 5 veces (según mis pruebas en MQL5), puedes sustituir estas funciones por una alternativa sencilla:
Dado que estas funciones se utilizan a menudo en bucles grandes y anidados, la ganancia de rendimiento puede ser bastante significativa.
Probablemente, el hecho de llamar a una función consume bastante tiempo (almacenamiento de diferentes datos, direcciones, etc.). Y en este caso se puede prescindir de las funciones.
Se adjunta el archivo del script con la prueba de rendimiento.