Question pour les experts en #define - page 5

 
Alexandr Andreev:

Donnez-moi le code complet de votre test

voilà, mais je ne vois pas l'intérêt de reparler de rand(), remplacez-le par une variable inc++.

#define    SpeedTest(count_x10,msg,EX)        {ulong mss=GetMicrosecondCount(); ulong count=(ulong)pow(10,count_x10);for(ulong _i=0;_i<count&&!_StopFlag;_i++){EX;} \
                                              printf("%s: loops = %llu seconds=%.4f",msg,count,(double)(GetTickCount()-mss)/1000000.0);}



//+------------------------------------------------------------------+
void OnStart()
{
   int arr1[], arr2[], arr3[];
   int cnt1 = ArrayResize(arr1, 100);
   int cnt2 = ArrayResize(arr2, 200);
   int cnt3 = ArrayResize(arr3, 300);
   ulong sum = 0;

   SpeedTest(3,"ArraySize",
      for(int i = 0; i < ArraySize(arr1); i++)
      {
         for(int j = 0; j < ArraySize(arr2); j++)
         {
            for(int k = 0; k < ArraySize(arr3); k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )
   
   SpeedTest(3,"cnt",
      for(int i = 0; i < cnt1; i++)
      {
         for(int j = 0; j < cnt2; j++)
         {
            for(int k = 0; k < cnt3; k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )

}


ouais... J'ai une erreur dans mon code, je veux sortir le temps en secondes, mais j'obtiens 10 fois plus, je l'ai divisé correctement par 1 000 000, qui peut me dire quelle est la raison ?

 
Igor Makanu:

voilà, mais je ne vois pas l'intérêt de reparler de rand(), ou alors de le remplacer par une variable inc++.


ouais... Une sorte d'erreur dans mon code, je veux sortir le temps en secondes, mais j'obtiens 10 fois plus, je l'ai divisé correctement par 1 000 000, qui peut me dire quelle est la raison ?

BOMB.

voici votre code qui prouve que c'est l'inverse.

//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#define    SpeedTest(count_x10,msg,EX)        {ulong mss=GetMicrosecondCount(); ulong count=(ulong)pow(10,count_x10);for(ulong _i=0;_i<count&&!_StopFlag;_i++){EX;} \
                                              printf("%s: loops = %llu seconds=%.4f",msg,count,(double)(GetTickCount()-mss)/1000000.0);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void OnStart()
{
   int arr1[], arr2[], arr3[];
   int cnt1 = ArrayResize(arr1, 100);
   int cnt2 = ArrayResize(arr2, 200);
   int cnt3 = ArrayResize(arr3, 300);
   ulong sum = 0;

   
   SpeedTest(3,"cnt",
      for(int i = 0; i < cnt1; i++)
      {
         for(int j = 0; j < cnt2; j++)
         {
            for(int k = 0; k < cnt3; k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )

   SpeedTest(3,"ArraySize",
      for(int i = 0; i < ArraySize(arr1); i++)
      {
         for(int j = 0; j < ArraySize(arr2); j++)
         {
            for(int k = 0; k < ArraySize(arr3); k++)
            {
               arr3[k] = rand();
               sum += arr3[k];
            }
            arr2[j] = rand();
            sum += arr2[j];
         }
         arr1[i] = rand();
         sum += arr1[i];
      }
   )
}
 
Alexandr Andreev:

BOMB

Voici votre code qui prouve le contraire.

J'ai juste échangé les chèques.

 
Alexandr Andreev:

J'ai juste échangé les chèques

2020.11.02 21:01:38.590 22222 (USDCHF,H1) cnt : boucles = 1000 secondes=821.7159

2020.11.02 21:01:52.353 22222 (USDCHF,H1) ArraySize : loops = 1000 seconds=807.9415


Il en ressort queArraySize est plus rapide que l'utilisation d'une variable =))) quelque chose ne va pas avec le test
 
Roman:

Quel test ? ))
Vous avez vous-même montré les deux variantes de la condition de cycle.
Igor a également donné le code ci-dessus.
Mesurez simplement les performances de la boucle avec une taille variable et avec ArraySize() dans la condition de la boucle.

Prouvez-moi que j'ai tort)

parce que dans mon test ils sont les mêmes

 
Alexandr Andreev:

J'ai juste échangé les chèques.

Oui, tu dois le faire.

J'étais trop paresseux cette fois.

J'ai mis les tests dans une boucle externe, comme ça :

2020.11.02 22:06:43.557 SpeedTst (EURUSD,H1) ArraySize : loops = 1000 seconds=117.4626

2020.11.02 22:06:58.328 SpeedTst (EURUSD,H1) cnt : boucles = 1000 secondes=102.7337

2020.11.02 22:07:13.075 SpeedTst (EURUSD,H1) ArraySize : loops = 1000 seconds=87.9782

2020.11.02 22:07:27.850 SpeedTst (EURUSD,H1) cnt : boucles = 1000 secondes=73.2461

2020.11.02 22:07:42.598 SpeedTst (EURUSD,H1) ArraySize : loops = 1000 seconds=58.4859

2020.11.02 22:07:57.380 SpeedTst (EURUSD,H1) cnt : boucles = 1000 secondes=43.7522

2020.11.02 22:08:12.891 SpeedTst (EURUSD,H1) ArraySize : loops = 1000 seconds=28.9861

2020.11.02 22:08:28.874 SpeedTst (EURUSD,H1) cnt : boucles = 1000 secondes=13.4910

 
Igor Makanu:

Oui, il faut le faire.

J'étais trop paresseux cette fois.

J'ai placé les tests dans une boucle externe, et j'ai obtenu ceci

2020.11.02 22:06:43.557 SpeedTst (EURUSD,H1) ArraySize : loops = 1000 seconds=117.4626

2020.11.02 22:06:58.328 SpeedTst (EURUSD,H1) cnt : boucles = 1000 secondes=102.7337

2020.11.02 22:07:13.075 SpeedTst (EURUSD,H1) ArraySize : loops = 1000 seconds=87.9782

2020.11.02 22:07:27.850 SpeedTst (EURUSD,H1) cnt : boucles = 1000 secondes=73.2461

2020.11.02 22:07:42.598 SpeedTst (EURUSD,H1) ArraySize : loops = 1000 seconds=58.4859

2020.11.02 22:07:57.380 SpeedTst (EURUSD,H1) cnt : boucles = 1000 secondes=43.7522

2020.11.02 22:08:12.891 SpeedTst (EURUSD,H1) ArraySize : loops = 1000 seconds=28.9861

2020.11.02 22:08:28.874 SpeedTst (EURUSD,H1) cnt : boucles = 1000 secondes=13.4910

Maintenant, échangez-les dans la boucle et soyez surpris.

 
Alexandr Andreev:

Maintenant, échangez-les dans la boucle et vous serez surpris.

Je ne serai pas surpris. Je sais que le compilateur peut optimiser le code à la volée.

mais, à mon avis, dans les boucles imbriquées, vous ne devriez toujours pas appeler ArraySize() inutilement.

for(int i = ArraySize(arr)-1; i >=0 ; i--)

Bien sûr, parfois cela peut être gênant, alors je fais la boucle via une variable temporaire - ta version № 2

imho, c'est fiable et vous comprenez ce qui va se passer

 

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. A titre d'exemple, ArraySize

Le résultat ;

for (int i=0 ; i<ArraySIze(mas) ; i++) == for (int i=0 ; i<size ; i++)


Mais si nous ajoutons l'initialisation de la variable taille à la deuxième partie, alors la première méthode prend la tête pour le temps d'initialisation de cette variable et de l'assimilation à la valeur.

 

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 :

for(int loop=0; loop <5;loop++)
   {
   int cnt1 = ArrayResize(arr1, 100+loop);
   int cnt2 = ArrayResize(arr2, 200+loop);
   int cnt3 = ArrayResize(arr3, 300+loop);
   
   SpeedTest(3,"cnt",
.....

Alexandr Andreev:

alors la première méthode est prioritaire, le temps d'initialiser cette variable et de lui assigner une valeur, cela ne se remarque qu'aux fortes répétitions

ça ne marche pas

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

vous ne pouvez pas tester des mashidas aussi simples sans le profiler, en général, vous pouvez écrire dans une boucle, ou vous pouvez tester dans le testeur, la vitesse est importante pour cela