Question pour les experts en #define - page 6

 
Igor Makanu:

Si vous modifiez la taille des tableaux dans le corps de la boucle, l'optimisation à la volée ne fonctionne pas.

alors changez le code :

)))) simplement vous devez aussi changer la valeur de votre variable de taille, donc la première méthode nommée utilisant ArraySIze sera avantageuse

 
Alexandr Andreev:

Je ne peux rien dire contre IMHO.

Sur des rediffusions très importantes, mes victoires sont devenues aléatoires pour la première et la deuxième méthode... Il est fort probable qu'il dépende du cache actuel du processeur et de la charge globale.

Ma question ne portait pas sur la boucle, mais sur le déroulement de la fonction. C'est juste que ArraySize a été utilisé comme exemple.

C'est bien) La perfection d'un langage de haut niveau est précisément lorsqu'une entrée pratique est aussi bon marché qu'une entrée non pratique mais initialement bon marché. Dommage que ce ne soit pas toujours comme ça, et l'aide d'un assistant pour les débutants pas toujours non plus..... il n'y aurait pas de questions))).

 
Igor Makanu:

Si vous modifiez la taille des tableaux dans le corps de la boucle, l'optimisation à la volée ne fonctionne pas.

Alors changez le code :


ça ne marche pas

l'optimisation du temps d'exécution est en tête

vous ne pouvez pas tester des commandes mashin aussi simples sans un profiler, ou vous pouvez écrire dans la boucle, ou tester dans un testeur, la vitesse est importante pour cela.

Je ne parlais pas de la boucle mais de la façon dont le compilateur déroule les fonctions..... allez.

Je vous laisse faire.

 
Alexandr Andreev:

)))) vous êtes également autorisé à modifier la valeur de votre variable de taille, de sorte que la première méthode utilisant ArraySIze l'emportera.

J'ai écrit ci-dessus - un code aussi simple ne peut pas être testé avec des mesures simples, il y a de nombreux facteurs - le code est petit - il tiendra dans le cache du processeur, le code doit être bien décomposé dans le processeur en micro-commandes parallèles dans le pipeline du processeur, c'est-à-dire que les registres seront rapidement chargés par la préextraction de données.

et peut-être que rand() sera aussi mis en cache quelque part


je ne sais pas comment tester sans débogueur - au moins là on peut voir le temps d'exécution des instructions dans les tacts

 
Alexandr Andreev:

Alors prouvez-moi que j'ai tort).

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

J'ai changé mon message.
Il me semble que ArraySize est maintenant plus rapide que la variable cnt.
Auparavant, c'était l'inverse. Peut-être que l'incrément cnt-- affecte, le corps de la boucle est différent et probablement quelque chose d'autre doit être inventé pour la charge.

void OnStart()
{
   int arr[];
   int sz = ArrayResize(arr, 100000000);  
   
   ulong t = GetMicrosecondCount();
   
   for(int i=0; i < ArraySize(arr); i++) 
   {
      ArrayResize(arr, sz--); //какая то нагрузка
   }   
   
   t = GetMicrosecondCount() - t;
   
   PrintFormat("Total time: %.3f ms", t / 1000.0);
}
2020.11.02 21:33:22.863 TestScript (USDJPY,M1)  Total time: 451.200 ms


void OnStart()
{
   int arr[];
   int sz = ArrayResize(arr, 100000000);  
   int cnt = ArraySize(arr);
   
   ulong t = GetMicrosecondCount();
   
   for(int i=0; i < cnt; i++) 
   {
      ArrayResize(arr, sz--);
      cnt--;
   }
      
   t = GetMicrosecondCount() - t;
   
   PrintFormat("Total time: %.3f ms", t / 1000.0);
}
2020.11.02 21:56:26.591 TestScript (USDJPY,M1)  Total time: 531.872 ms
 
Roman:

C'est étrange.
L'utilisation de ArraySize(arr) dans la condition de la boucle est plus rapide que l'utilisation de la variable cnt.
C'était l'inverse avant. C'est peut-être une erreur ? Ça ne devrait pas être comme ça.

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

cnt

le changer pour vous, comme c'est le cas dans la première variante

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

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

Question de 500 p (sans contrôle), quelle est la méthode la plus rapide ? Voyez combien de fonctions externes sont appelées dans la méthode supérieure.

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

comme une variante du test - vous pouvez aussi glisser seulement des tableaux différents dans chaque test - dans mon exemple arr1,arr2....

c'est-à-dire tst1_arr1[],tst1_arr2[] .... et tst2_arr1[],tst2_arr2[]


ce serait un test plus juste.

je m'en vais, très distrayant - imho, pratique, à utiliser

 
Igor Makanu:

Je ne sais pas comment tester sans débogueur - au moins, vous pouvez voir le temps d'exécution des instructions en cycles d'horloge.

Eh bien, oui - vous ne pouvez pas vous passer du débogueur. Et dans le temps de l'horloge, il y a...

 
Roman:

C'est étrange.
L'utilisation de ArraySize(arr) dans la condition de la boucle est plus rapide que l'utilisation de la variable cnt.
C'était l'inverse avant. C'est peut-être une erreur ? Ça ne devrait pas être comme ça.

Il y a là un résultat aléatoire. Lors de la compilation, les accès à une cellule de mémoire avec une valeur de taille de tableau sont dépliés, tandis que la taille du tableau sera reçue et placée dans la cellule de mémoire au préalable, lorsque le tableau est formé, même si le tableau est dynamique et que les cellules avec une taille de tableau et une valeur de 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 d'encadrement suffisamment nécessaire ne me rendra pas très nerveux dans un environnement MCL)