Question pour les experts en #define - page 7

 
Alexandr Andreev:

Vous n'avez rien mélangé dans votre code, qui va changer la valeur pour vous ?

comme c'est le cas dans la première version.

Oui, j'ai raté ce point. J'ai corrigé mon message.

 
Valeriy Yastremskiy:

Il y a un résultat aléatoire là. La compilation déroule l'accès à une cellule de mémoire avec une valeur de taille de tableau, et la taille du tableau sera obtenue et placée dans la cellule de mémoire à l'avance, lorsque le tableau est formé, même si le tableau est dynamique, et les cellules avec une taille de tableau et avec une valeur variable auront le même temps d'accès.

Et à en juger par la phrase que les compilateurs font dans le cours d'informatique de 3-4 ans ... en général, j'espère qu'un niveau de personnel suffisamment adéquat ne me rendra pas très nerveux dans l'environnement MCL)

Croyez-moi l'étudiant moyen habituellement FIVT est juste zéro avec plus), puisqu'il y a zéro expérience, et la connaissance sans expérience va rapidement nulle part (oubliée), et leurs exemples sont très étranges, il faudra des années avant que l'étudiant comprenne où et comment ils peuvent être utilisés. Et ce, si vous le comparez à un programmeur expérimenté.

 
Alexandr Andreev:

Croyez-moi, l'étudiant moyen du FIVT est généralement un zéro plus), parce qu'il n'a aucune expérience, et la connaissance sans expérience ne va rapidement nulle part (est oubliée), et leurs exemples sont très étranges, il faudra des années avant que l'étudiant comprenne où et comment ils peuvent être utilisés. Et ce, si vous le comparez à un programmeur expérimenté.

C'est compréhensible. Je ne comprends pas pourquoi il faut enseigner comment faire un compilateur. C'est comme enseigner comment créer sa propre langue. Il est clair qu'une langue est une classe, mais tous les oiseaux ne savent pas voler a priori. Eh bien, comme je l'ai déjà mentionné ci-dessus, Erreurs, bogues, questions sont également pertinents pour la question de l'optimisation de la compilation à la volée.

 

Le sujet concerne les définitions, pas les boucles ;))

Mais je ne comprends toujours pas, y a-t-il un sens à définir du code, par exemple, des fonctions définies par l'utilisateur.
Dans l'espoir que le code défectueux sera exécuté plus rapidement dans le fichier exécutable.
Ou est-ce un malentendu ? Parce que la substitution n'est qu'une action de précompilation, et qu'elle n'a de sens que pour accélérer la compilation.

 
Roman:

Le sujet concerne les définitions, pas les boucles ;))

Mais je ne comprends toujours pas, y a-t-il un sens à définir du code, par exemple, des fonctions définies par l'utilisateur.
Dans l'espoir que le code défectueux sera exécuté plus rapidement dans le fichier exécutable.
Ou est-ce un malentendu ? Parce que la substitution n'est qu'une action de précompilation, et qu'il est logique d'accélérer la compilation.

Je viens de vous montrer un exemple où 3 fonctions externes sont utilisées... contre sa forme dépliée. Il n'y aura donc pas d'accélération.

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

Question pour les experts 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 question (sans vérifier) qui est le plus rapide. voir combien de fonctions externes sont appelées dans la méthode supérieure.


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

Je vous ai donné un exemple où 3 fonctions externes sont utilisées... contre sa forme dépliée. Il n'y aura donc pas d'accélération.


Je vois. Alors bonjour à fxsaber. Un gars qui aime tout déflorer.


Alexandr Andreev:

Prouvez-moi que j'ai tort)

parce que dans mon test ils sont les mêmes pour une raison quelconque.

Comme pour ArraySize() et la variable. Je reviendrai quand même sur cette question.
Voici ce que j'ai changé dans le test. La boucle compte le nombre d'IP.
Dans le premier exemple, la condition de la boucle utilise ArraySize().
Dans le deuxième exemple, la variable num_steps est utilisée.
Il y a une différence.

Fonction 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);
}

Trois passages du scénario.

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 num_steps.

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);
}

Trois passages du scénario.

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:

Je vois. Alors bonjour à fxsaber. Un fan de la définition de tout en rang.

Comme pour ArraySize() et la variable. Je reviendrai tout de même à cette question.
Voici le test que j'ai modifié. La boucle compte le nombre d'IP.
Dans le premier exemple, la condition de la boucle utiliseArraySize().
Dans le deuxième exemple, la variable
num_steps est utilisée.
Il y a une différence.

Fonction ArraySize()

Trois passages du scénario.


Variable num_steps.

Trois passages du scénario.

Pas de différence évidente dans ces calculs. J'ai mis tout cela dans un seul code et les résultats sont différents, il y en a un où la première variante gagne

)) tout tableau dans µl possède une variable qui est responsable de la taille actuelle du tableau, donc dans la plupart des langues.

La fonction ArraySize indique au compilateur de retourner la valeur de cette variable, c'est-à-dire qu'il substitue cette variable au lieu de cette fonction. Comme les tableaux µl ne peuvent pas être référencés, le pointeur est explicitement sur cette variable, à l'adresse de la crocette en mémoire. Techniquement, tous ces tests sont une tentative de comparer deux variables régulières. C'est la propriété des fonctions de dépliage, dans mon exemple 4 fonctions pardonnent 0 fonctions, dont 3 sont juste dans le corps de la boucle c'est-à-dire qu'il y a une comparaison de 40000000000 d'appels de fonctions contre aucun. Et nous voyons une différence implicite qui est trop petite pour être remarquée - parce qu'elle met du code dans le fichier exécutable..... nous comparons la même chose.

Et tous ces calculs - plus ils sont compliqués, moins ils ont de sens.

Il est plus facile de donner un exemple où dans un cas on appelle une centaine de fonctions, des fonctions dans des fonctions... Et dans l'autre cas, tout cela sous forme élargie - et il n'y aura aucune différence. Puisque ArraySize(mas)== mas[].taille

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

Bien que, pour une raison quelconque, l'exemple pi présente une différence ..... par la fréquence de dépassement, (rédaction) bien qu'il s'agisse d'un dépassement purement aléatoire.

et il est égal à 1ms pour 1 milliard de sorties, bien que cela ne soit pas explicitement essayé en comparant les variables entre elles et la dispersion devient encore plus grande))


 
Alexandr Andreev:

Pas de différence nette avec ces calculs. Mettez tout dans un seul code, et les résultats sont différents, il y en a où la première option gagne

)) Chaque tableau dans µl possède une variable responsable de la taille actuelle du tableau, donc dans la plupart des langages.

La fonction ArraySize indique au compilateur de retourner la valeur de cette variable, c'est-à-dire qu'il substitue cette variable au lieu de cette fonction. Comme les tableaux µl ne peuvent pas être référencés, le pointeur est explicitement sur cette variable, à l'adresse de la crocette en mémoire. Techniquement, tous ces tests sont une tentative de comparer deux variables régulières. C'est la propriété des fonctions de dépliage, dans mon exemple 4 fonctions pardonnent 0 fonctions, dont 3 sont juste dans le corps de la boucle c'est-à-dire qu'il y a une comparaison de 40000000000 d'appels de fonctions contre aucun. Et nous voyons une différence implicite qui est trop petite pour être remarquée - parce qu'il s'agit de mettre du code dans le fichier exécutable..... nous comparons la même chose.

Et tous ces calculs - plus ils sont compliqués, moins ils ont de sens.

Il est plus facile de donner un exemple où dans un cas on appelle une centaine de fonctions, des fonctions dans des fonctions... Et dans l'autre cas, tout cela sous forme élargie - et il n'y aura aucune différence. Puisque ArraySize(mas)== mas[].taille

Ce qui est exécuté dans le corps de la boucle n'a pas d'importance. C'est juste une charge pour le test.
Les exemples comparent la référence à une fonction ou à une variable dans la condition de boucle.

Je ne suis pas assembleur, mais je pense que ce n'est pas la même chose du point de vue des instructions de l'assembleur.
Et si elle est également enveloppée dans une classe, ce n'est certainement pas la même chose.

Une fonction possède une instruction supplémentaire pour récupérer une valeur dans une cellule de mémoire, c'est-à-dire que la fonction appelle la cellule de mémoire pour obtenir une valeur et ne renvoie qu'ensuite le résultat.
Une variable a déjà cette valeur ; la variable ne référence rien ; elle renvoie le résultat immédiatement.

 
Roman:

Peu importe ce qui est réalisé dans le corps du cycle. C'est juste une charge pour le test.
Les exemples comparent la référence à une fonction ou à une variable dans la condition de boucle.

Je ne suis pas un expert en assembleur, mais je pense que du point de vue des instructions d'assemblage, ce n'est pas la même chose.
Et si elle est également enveloppée dans une classe, ce n'est certainement pas la même chose.

Une fonction possède une instruction supplémentaire pour récupérer une valeur dans une cellule de mémoire, c'est-à-dire que la fonction appelle la cellule de mémoire pour obtenir une valeur et ne renvoie qu'ensuite le résultat.
Une variable a déjà cette valeur, la variable ne fait référence nulle part, elle renvoie le résultat immédiatement.

) Eh bien, ce n'est pas comme ça que ça marche)

 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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();}

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

Presque à chaque course, le leader change

le plus long est la division))))