pregunta para los expertos en #define - página 7

 
Alexandr Andreev:

No has mezclado nada en tu código, ¿quién va a cambiar el valor por ti?

como en la primera versión.

Sí, me perdí ese punto. Corregido mi post.

 
Valeriy Yastremskiy:

Ahí hay un resultado aleatorio. La compilación despliega el acceso a una celda de memoria con un valor de tamaño de matriz, y el tamaño de la matriz se obtendrá y se colocará en la celda de memoria por adelantado, cuando se forme la matriz, incluso si la matriz es dinámica, y las celdas con un tamaño de matriz y con un valor variable tendrán el mismo tiempo de acceso.

Y a juzgar por la frase que hacen los compiladores en el curso de informática de 3-4 años... en general, espero que un nivel de personal suficientemente necesario no me ponga muy nervioso en el entorno de la ACM)

Créanme que el estudiante promedio por lo general FIVT es sólo cero con más), ya que hay cero experiencia, y el conocimiento sin experiencia rápidamente va a ninguna parte (olvidado), y sus ejemplos son muy extraños, se tardará años antes de que el estudiante entiende dónde y cómo se puede utilizar. Esto es si lo comparas con un programador experimentado.

 
Alexandr Andreev:

Créanme, el estudiante promedio de FIVT suele ser un cero más), porque hay cero experiencia, y el conocimiento sin experiencia rápidamente no va a ninguna parte (se olvida), y sus ejemplos son muy extraños, pasarán años antes de que el estudiante entienda dónde y cómo se pueden utilizar. Esto es si lo comparas con un programador experimentado.

Es comprensible. No entiendo por qué hay que enseñar a hacer un compilador. Está claro que una lengua es una clase, pero no todos los pájaros pueden volar a priori. Bueno, como ya he mencionado anteriormente, Errores, Bugs, Preguntas también son relevantes para la cuestión de la optimización de la compilación sobre la marcha.

 

El tema es sobre definiciones, no sobre bucles ))

Pero sigo sin entender, si tiene sentido definir código, por ejemplo, funciones definidas por el usuario.
Con la esperanza de que el código defectuoso se ejecute más rápido en el archivo ejecutable.
¿O es un malentendido? Porque la sustitución es sólo una acción de precompilación, y sólo tiene sentido para acelerar la construcción.

 
Roman:

El tema es sobre definiciones, no sobre bucles ))

Pero sigo sin entender, si tiene sentido definir código, por ejemplo, funciones definidas por el usuario.
Con la esperanza de que el código defectuoso se ejecute más rápido en el archivo ejecutable.
¿O es un malentendido? Porque la sustitución es sólo una acción de precompilación, y es lógico que acelere la compilación.

Acabo de mostrar un ejemplo en el que se utilizan 3 funciones externas... contra su forma desplegada. Así que no habrá aceleración.

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

Pregunta para los expertos en #define

Alexandr Andreev, 2020.11.02 19:49

void OnStart()
  {
   int mas[];
   int size=1000000;
   ArrayResize(mas,size);
   ulong r=0;
   ulong r1=0;
   ulong r2=0;
   int random;
   ulong max=100;
   uint t1=GetTickCount();
   int t=0;
   int tr=0; 
   MathSrand(10);
   for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<ArraySize(mas); Funk(i))
        { 
         FunkRand(r1); 
         Funk(r);// мы сюда написали вызов еще одной функции чтобы усложить ситуацию
        }
     }
   tr=r;
   uint t2=GetTickCount();
   for(ulong z=0; z<max; z++)
     {
     int v=size;
      for(ulong i=0; i<v; i++)
        { 
         r2+=rand();
         r--;
        }

     }

   uint t3=GetTickCount();
   Print(t2-t1,"  ",t3-t2," ",r," ",r1," ",r2," ",t1," ",tr);
// Templ();
  }

//+------------------------------------------------------------------+
//|                                           
  
void Funk(ulong &a){a++;}
void FunkRand(ulong &a){a+=rand();}

//+------------------------------------------------------------------+

500p pregunta (sin comprobar) qué camino es más rápido. ver cuántas funciones externas se llaman en el método superior


Документация по MQL5: Основы языка / Функции / Описание внешних функций
Документация по MQL5: Основы языка / Функции / Описание внешних функций
  • www.mql5.com
Внешние функции, определенные в другом модуле, должны быть явно описаны. Описание включает в себя тип возвращаемого значения, имя функции и набор входных параметров с их типами. Отсутствие такого описания может привести к ошибкам при компиляции, компоновке или выполнении программы. При описании внешнего объекта используйте ключевое слово С...
 
Alexandr Andreev:

Acabo de mostrar un ejemplo en el que se utilizan 3 funciones externas... contra su forma desplegada. Así que no habrá aceleración.


Ya veo. Entonces, hola a fxsaber. Un fanático de la desfinanciación de todo.


Alexandr Andreev:

Demuestra que me equivoco)

porque en mi prueba son iguales por alguna razón.

En cuanto a ArraySize() y la variable. Aún así, volveré a esta cuestión.
Esto es lo que he cambiado en la prueba. El bucle cuenta el número de PI.
En el primer ejemplo, la condición del bucle utiliza ArraySize().
En el segundo ejemplo, se utiliza la variable num_steps.
Hay una diferencia.

Función ArraySize()

void OnStart()
{
    int arr[];
    int num_steps = ArrayResize(arr, 1000000000);

    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
    ulong t = GetMicrosecondCount();
    
    for (int i = 0; i<ArraySize(arr); i++)
    {
       x = (i + .5) * step;
       sum = sum + 4.0 / (1.0 + x * x);
    }
    
    pi = sum*step;
        
    t = GetMicrosecondCount() - t;
   
   printf("The value of PI is %1.12f ", pi);
   PrintFormat("Total time to calculate PI was %5.3f ms\n", t / 1000.0);
}

Tres ejecuciones del guión.

2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  Total time to calculate PI was 4049.179 ms
2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  Total time to calculate PI was 4183.364 ms
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  
2020.11.02 23:57:03.884 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:57:03.884 TestScript (USDJPY,M1)  Total time to calculate PI was 4034.098 ms
        


Variable número_pasos.

void OnStart()
{
    int arr[];
    int num_steps = ArrayResize(arr, 1000000000);

    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
    ulong t = GetMicrosecondCount();
    
    for (int i = 0; i<num_steps; i++)
    {
        x = (i + .5) * step;
        sum = sum + 4.0 / (1.0 + x * x);
    }
    
    pi = sum*step;
        
    t = GetMicrosecondCount() - t;
   
   printf("The value of PI is %1.12f ", pi);
   PrintFormat("Total time to calculate PI was %5.3f ms\n", t / 1000.0);
}

Tres ejecuciones del guión.

2020.11.03 00:08:09.269 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:09.271 TestScript (USDJPY,M1)  Total time to calculate PI was 3955.325 ms
2020.11.03 00:08:09.271 TestScript (USDJPY,M1)  
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  Total time to calculate PI was 3950.568 ms
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  
2020.11.03 00:08:22.469 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:22.469 TestScript (USDJPY,M1)  Total time to calculate PI was 3927.110 ms
        
 
Roman:

Ya veo. Entonces, hola a fxsaber. Un fanático de definir todo en una fila.

En cuanto a ArraySize() y la variable. De todos modos, volveré a esta pregunta.
Aquí está la prueba que he modificado. El bucle cuenta el número de PI.
En el primer ejemplo, la condición del bucle utilizaArraySize().
En el segundo ejemplo,
se utilizala variable num_steps.
Hay una diferencia.

Función ArraySize()

Tres ejecuciones del guión.


Variable número_pasos.

Tres ejecuciones del guión.

No hay una diferencia clara en estos cálculos. Puse todo esto en un código y los resultados son diferentes, hay uno donde la primera variante gana

)) cualquier matriz en µl tiene una variable que es responsable del tamaño actual de la matriz, por lo que en la mayoría de los lenguajes

La función ArraySize le dice al compilador que devuelva el valor de esta variable, es decir, sustituye esta variable en lugar de esta función. Como los arrays µl no pueden ser referenciados, el puntero es explícitamente a esta variable, justo a la dirección de la croqueta en memoria. Técnicamente, todas estas pruebas son un intento de comparar dos variables regulares. Esta es la propiedad de las funciones de desdoblamiento, en mi ejemplo 4 funciones perdonan 0 funciones, 3 de las cuales están justo en el cuerpo del bucle, es decir, hay una comparación de 40000000000 llamadas a funciones frente a ninguna. Y vemos una diferencia implícita que es demasiado pequeña para notarla - porque está poniendo código en el archivo ejecutable.... estamos comparando lo mismo.

Y todos estos cálculos, cuanto más complicados son, menos sentido tienen.

Es más fácil poner un ejemplo en el que en un caso llamamos a cien funciones, funciones dentro de funciones... Y en el otro caso, todo esto en forma expandida - y no habrá ninguna diferencia. Ya que ArraySize(mas)== mas[].tamaño

Документация по MQL5: Операции с массивами / ArraySize
Документация по MQL5: Операции с массивами / ArraySize
  • www.mql5.com
"Нулевое измерение = Размер массива / (Первое измерение * Второе измерение * Третье измерение)"
 

Aunque por alguna razón el ejemplo de pi tiene una diferencia ..... por la frecuencia de rebasamiento, (redacción) aunque esto es puramente aleatorio rebasamiento

y es igual a 1ms por 1.000 millones de salidas, aunque no se prueba explícitamente comparando variable con variable y la dispersión se hace aún mayor)


 
Alexandr Andreev:

No hay una diferencia clara con estos cálculos. Ponerlo todo en un código, y los resultados son diferentes, hay algunos en los que gana la primera opción

)) Cada matriz en µl tiene una variable responsable del tamaño actual de la matriz, por lo que en la mayoría de los lenguajes

La función ArraySize le dice al compilador que devuelva el valor de esta variable, es decir, sustituye esta variable en lugar de esta función. Como las matrices µl no pueden ser referenciadas, el puntero es explícitamente a esta variable, justo a la dirección de la croqueta en memoria. Técnicamente, todas estas pruebas son un intento de comparar dos variables regulares. Esta es la propiedad de las funciones de desdoblamiento, en mi ejemplo 4 funciones perdonan 0 funciones, 3 de las cuales están justo en el cuerpo del bucle, es decir, hay una comparación de 40000000000 llamadas a funciones frente a ninguna. Y vemos una diferencia implícita que es demasiado pequeña para notarla - porque está poniendo código en el archivo ejecutable.... estamos comparando lo mismo.

Y todos estos cálculos, cuanto más complicados son, menos sentido tienen.

Es más fácil poner un ejemplo en el que en un caso llamamos a cien funciones, funciones dentro de funciones... Y en el otro caso, todo esto en forma expandida - y no habrá ninguna diferencia. Ya que ArraySize(mas)== mas[].tamaño

No importa lo que se ejecute en el cuerpo del bucle. Esto es sólo una carga para la prueba.
Los ejemplos comparan la referencia a una función o variable en la condición del bucle.

No soy ensamblador, pero creo que no es lo mismo desde el punto de vista de las instrucciones del ensamblador.
Y si además está envuelto en una clase, ciertamente no es lo mismo.

Una función tiene una instrucción extra para recuperar un valor de una celda de memoria, es decir, la función llama a la celda de memoria para obtener un valor y sólo entonces devuelve el resultado.
Una variable ya tiene este valor, la variable no hace referencia a ningún sitio, devuelve el resultado inmediatamente.

 
Roman:

No importa lo que se realice en el cuerpo del ciclo. Es sólo una carga para la prueba.
Los ejemplos comparan la referencia a una función o variable en la condición del bucle.

No soy experto en ensamblador, pero creo que desde el punto de vista de las instrucciones de ensamblador, no es lo mismo.
Y si además está envuelto en una clase, ciertamente no es lo mismo.

Una función tiene una instrucción adicional para recuperar un valor de una celda de memoria, es decir, la función llama a la celda de memoria para obtener un valor y sólo entonces devuelve el resultado.
Una variable ya tiene ese valor, la variable no hace referencia a ningún sitio, devuelve el resultado inmediatamente.

) Bueno, no es así como funciona)

 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   int mas[];
   int mas1[300];
   int mas2[300];
   int mas3[300];
   int mas4[300];
   int mas5[300];
   int mas6[300];
   int z=300;
   int size=100000000;
   ArrayResize(mas,size);
   ulong r=0;
   ulong r1=0;
   ulong r2=0;
   int random;
   ulong max=100; 
   int t=0;
   int tr=0; 
   MathSrand(10);
    int num_steps=ArraySize(mas);
    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
     int v=size;
    ulong t1 = GetMicrosecondCount();
     
    
  // for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<ArraySize(mas); i++)
        { 
        r2+=ArraySize(mas);
        r2+=ArraySize(mas1);
        r2+=ArraySize(mas2);
        r2+=ArraySize(mas3);
        r2+=ArraySize(mas4);
        r2+=ArraySize(mas5);
        r2+=ArraySize(mas6);
        r2+=ArraySize(mas1);
        r2+=ArraySize(mas2);
        r2+=ArraySize(mas3);
        r2+=ArraySize(mas4);
        r2+=ArraySize(mas5);
        r2+=ArraySize(mas6);
        r2+=ArraySize(mas1);
        r2=r2/10;
        }

     }  
   ulong t2=GetMicrosecondCount();
   //for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<v; i++)
        { 
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1=r1/10;
        }
     }
   
   int pi2 = sum*step;
   ulong t3=GetMicrosecondCount();
   Print(t2-t1,"  ",t3-t2," ",r," ",r1," ",r2," ",pi," ",pi2);
// Templ();
  }

//+------------------------------------------------------------------+
//|                                           
  
void Funk(ulong &a){a++;}
void FunkRand(ulong &a){a+=rand();}

//+------------------------------------------------------------------+

Casi cada carrera el líder cambia

la más larga es la división)))