¿Declaración de variables detrás del bucle o dentro del bucle? - página 4

 

Lo siento amigos, la optimización ha sido desactivada en la configuración del proyecto

Código:

   CStopWatch sw; // Секундомер, для замера времени
   
   sw.Start();
   for (int i = 0; i < 10000000; i++)
   {
      string st = (string)i;
   }
   pr("Test1, время выполнения: " + sw.Stop());

   sw.Start();
   string st = "";
   for (int i = 0; i < 10000000; i++)
   {
      st = (string)i;
   }
   pr("Test2, Время выполнения: " + sw.Stop());


No optimizado

Test1, время выполнения: 0.548275 сек.
Test2, Время выполнения: 0.313978 сек.

Con la optimización

Test1, время выполнения: 0.420523 сек.
Test2, Время выполнения: 0.545999 сек.

Con la optimización sí, es lo contrario, lo he comprobado muchas veces

 
Aleksandr Matveev:

Primero deberías aprender lo básico y luego demostrar tu punto de vista. Entenderías el resultado sin necesidad de hacer pruebas, si hubieras leído al menos un libro sobre el funcionamiento de la CPU y la memoria. Te he ofrecido el más ingenioso y si quieres avanzar un poco en la programación seguro que lo lees.

¿Qué tiene que ver la memoria y la CPU? Se trata de la optimización, teórico de libro).

 
Igor Makanu:

no es extraño, es necesario poder probar los operadores y operaciones más simples en MQL - ¿por qué iba a añadir srand(GetTickCount()) a mi prueba? ?

;)

Por cierto, fíjate bien, el resultado en tu bucle no se tiene en cuenta de ninguna manera, lo que significa que puede ser fácilmente recortado por el compilador.

 
Alexey Navoykov:

Por cierto, me fijé bien, el resultado en tu bucle no se tiene en cuenta de ninguna manera, por lo que el compilador puede cortarlo fácilmente.

Eliminado incluso rand() - su compilador lo inlinea perfectamente, hecho tal prueba:

#define  N 8

#define    test(M,S,EX) {                                 \
uint mss=GetTickCount();                                 \
ulong nn=(ulong)pow(10,M);                               \
for(ulong tst=0;tst<nn && !_StopFlag;tst++) \
{ EX; }                                                  \
printf("%s: loops=%i ms=%u",S,nn,GetTickCount()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   string s1;  test(N,"1. s1=rand()",s1=(string)tst);
   string s2;  test(N,"2. s2=rand()",s2=(string)tst);
   string s3;  test(N,"3. s3=rand()",s3=(string)tst);
   string s4;  test(N,"4. s4=rand()",s4=(string)tst);
   string s5;  test(N,"5. s5=rand()",s5=(string)tst);

   test(N,"1. q=rand()",string q=(string)tst);
   test(N,"2. q=rand()",string q=(string)tst);
   test(N,"3. q=rand()",string q=(string)tst);
   test(N,"4. q=rand()",string q=(string)tst);
   test(N,"5. q=rand()",string q=(string)tst);
  }
//+------------------------------------------------------------------+

2019.08.18 11:55:41.457 SpeedTest (EURUSD,H1) 1. s1=rand(): loops=100000000 ms=7672

2019.08.18 11:55:49.085 SpeedTest (EURUSD,H1) 2. s2=rand(): loops=100000000 ms=7625

2019.08.18 11:55:56.796 SpeedTest (EURUSD,H1) 3. s3=rand(): loops=100000000 ms=7719

2019.08.18 11:56:04.495 SpeedTest (EURUSD,H1) 4. s4=rand(): loops=100000000 ms=7703

2019.08.18 11:56:12.113 SpeedTest (EURUSD,H1) 5. s5=rand(): loops=100000000 ms=7610

2019.08.18 11:56:17.695 SpeedTest (EURUSD,H1) 1. q=rand(): loops=100000000 ms=5578

2019.08.18 11:56:23.362 SpeedTest (EURUSD,H1) 2. q=rand(): loops=100000000 ms=5672

2019.08.18 11:56:28.970 SpeedTest (EURUSD,H1) 3. q=rand(): loops=100000000 ms=5609

2019.08.18 11:56:34.637 SpeedTest (EURUSD,H1) 4. q=rand(): loops=100000000 ms=5672

2019.08.18 11:56:40.277 SpeedTest (EURUSD,H1) 5. q=rand(): loops=100000000 ms=5640


 
Alexey Navoykov:

Así que digo, si quieres "hacerlo bien", entonces ve a ensamblador. Si necesitas controlar todo tú mismo... Después de todo, el caso que acaba de describir no es nada. Hay cosas mucho más complicadas. El OOP está definitivamente contraindicado para ti. No sabrás si el compilador ha degenerado o no un método virtual concreto en una llamada normal, o si ha cortado una comprobación de punteros innecesaria... ¿Qué puedes hacer en un MQL gestionado con semejante paranoia? )

Y ajustar el código a las peculiaridades del compilador (y a las imaginarias), en detrimento de la corrección y la fiabilidad del código, no es, obviamente, lo que debe hacer un buen programador. Y aquí estamos hablando de incorrección del código. La variable debe declararse directamente en el bloque en el que se utiliza.

Ja, ja, ja... Alexey, afirmas (seamos "tú") que "la OOP está definitivamente contraindicada" a uno de los principales adeptos a la OOP del foro.

El código no debe ajustarse a las peculiaridades del compilador, sino a las peculiaridades del pensamiento propio. En este caso, la declaración de una variable dentro de un bucle reduce en teoría la eficiencia. Porque según las convenciones, la variable debe ser creada cada vez y destruida cada vez.

Ni siquiera es una cuestión de eficiencia. Un código sólido es un código transparente, claro y fácil de modificar y mantener.

Personalmente no me gusta tener un montón de variables dispersas por todo el programa y tener que buscar cada vez donde se crea una variable en particular. Por lo tanto, si es posible, trato de declarar las variables al principio de la función, todas juntas, para ver dónde se crean y entender cuándo se van a eliminar.

En este caso, el ejemplo es muy corto. Cuando hay docenas de líneas y un montón de funciones anidadas entre la creación de una variable y su uso - para mí, es mucho más fiable cuando la variable se declara fuera del bloque, por adelantado.

 
pivalexander:

Lo siento amigos, la optimización se ha desactivado en la configuración del proyecto

Código:


No optimizado

Con la optimización

Con la optimización, sí, es lo contrario, lo he comprobado muchas veces.

En tu ejemplo, se podría haber recortado todo el cuerpo del bucle con la optimización.

 

En general, todo se ajusta a lo esperado, que no hay necesidad de hacer tonterías, buscando problemas inexistentes y creando otros reales.

Si te pica el gusanillo y te crees un hacker guay, escribe en ensamblador, o bien apártate y deja que el compilador haga su trabajo.

 
Aleksandr Matveev:

En este ejemplo, todo el cuerpo del bucle podría haberse recortado mediante la optimización.

El resultado de ejecutar con un cuerpo de bucle vacío, muy diferente, funciona mucho más rápido

Без оптимизации:
Test1, время выполнения: 0.027539 сек.

С оптимизацией:
Test1, время выполнения: 0.005448 сек.
 
Alexey Navoykov:

En general, todo se ajusta a lo esperado, que no hay necesidad de hacer tonterías, buscando problemas inexistentes y creando otros reales.

Si te pica el gusanillo y te crees un hacker guay, escribe en ensamblador. Si no, apártate y deja que el compilador haga su trabajo.

El principal problema es precisamente que no me considero un coolhacker. Por eso las variables, en mi opinión, deben declararse fuera del bucle. Y mejor: al principio de la función, de una vez.

Y sólo los koolhousers pueden declarar variables según sea necesario, dentro del código.

 
Georgiy Merts:

El principal problema es precisamente que no me considero un coolhacker. Por eso las variables, en mi opinión, deben declararse fuera del bucle. Y preferiblemente al principio de la función, de una vez.

Los Koolhackers pueden declarar variables según sea necesario dentro del código.

Prefiero dividir mi código en bloques lógicos y declarar las variables necesarias para ellos en esos bloques en lugar de crear un montón de variables al principio de una función, la mayoría de las cuales sólo se necesitan en un bloque, en algún lugar más abajo

Razón de la queja: