Déclarer les variables derrière la boucle ou à l'intérieur de la boucle ? - page 4

 

Désolé les gars, l'optimisation a été désactivée dans les paramètres du projet.

Code :

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


Non optimisé

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

Avec l'optimisation

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

Avec l'optimisation, oui, c'est le contraire, j'ai vérifié à plusieurs reprises.

 
Aleksandr Matveev:

Vous devriez d'abord apprendre les bases et ensuite prouver votre point de vue. Vous comprendriez le résultat sans aucun test, si vous aviez lu au moins un livre sur le fonctionnement du CPU et de la mémoire. Je vous ai proposé le plus ingénieux d'entre eux et si vous voulez progresser un peu en programmation, vous êtes sûr de le lire.

Qu'est-ce que la mémoire et le processeur ont à voir avec cela ? Il s'agit d'optimisation, espèce de théoricien livresque).

 
Igor Makanu:

Ce n'est pas étrange, vous devez être capable de tester les opérateurs et les opérations les plus simples en MQL - pourquoi ajouterais-je srand(GetTickCount()) à mon test ? ?

;)

D'ailleurs, regardez bien, le résultat dans votre boucle n'est en aucun cas pris en compte, ce qui signifie qu'il peut être facilement coupé par le compilateur.

 
Alexey Navoykov:

D'ailleurs, j'ai regardé de près, le résultat dans votre boucle n'est en aucun cas pris en compte, donc le compilateur peut facilement le couper.

Supprimé même rand() - son compilateur l'inline parfaitement, fait un tel test :

#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:

Donc je dis, si vous voulez "bien faire les choses", alors allez à l'assembleur. Si vous devez tout contrôler vous-même... Après tout, le cas que vous venez de décrire n'est rien du tout. Il y a des choses bien plus compliquées. La POO est définitivement contre-indiquée pour vous. Vous ne saurez pas si le compilateur a dégénéré une méthode virtuelle particulière en un appel régulier ou a supprimé une vérification de pointeur inutile... Que pouvez-vous faire dans un MQL géré avec une telle paranoïa ? )

Et adapter le code aux particularités du compilateur (qui plus est, imaginaires), au détriment de la correction et de la fiabilité du code, n'est évidemment pas ce que doit faire un bon programmeur. Et nous parlons ici de correction du code. Une variable doit être déclarée directement dans le bloc dans lequel elle est utilisée.

Ha ha ha... Alexey, vous affirmez (soyons "vous") que "OOP est définitivement contre-indiqué" à l'un des principaux adeptes de OOP sur le forum.

Le code ne doit pas être adapté aux particularités du compilateur, mais aux particularités de sa propre pensée. Dans ce cas, la déclaration d'une variable à l'intérieur d'une boucle réduit en théorie l'efficacité. Car selon les conventions, la variable doit être créée à chaque fois et détruite à chaque fois.

Ce n'est même pas une question d'efficacité. Un code solide est un code transparent, clair et facile à modifier et à maintenir.

Personnellement, je n'aime pas avoir beaucoup de variables éparpillées dans le programme et devoir chercher à chaque fois où une variable particulière est créée. Par conséquent, si possible, j'essaie de déclarer les variables au début de la fonction, toutes ensemble - juste pour voir où elles sont créées et comprendre quand elles seront supprimées.

Dans ce cas, l'exemple est juste très court. Quand il y a des dizaines de lignes et un tas de fonctions imbriquées entre la création d'une variable et son utilisation - pour moi, c'est beaucoup plus fiable quand la variable est déclarée à l'extérieur du bloc, à l'avance.

 
pivalexander:

Désolé les gars, l'optimisation a été désactivée dans les paramètres du projet.

Code :


Non optimisé

Avec l'optimisation

Avec l'optimisation, oui, c'est le contraire, je l'ai vérifié plusieurs fois.

Dans votre exemple, le corps entier de la boucle aurait pu être coupé avec optimisation.

 

En général, tout se passe comme prévu, il n'est pas nécessaire de faire des bêtises, de chercher des problèmes inexistants et de créer des problèmes réels.

Si cela vous démange et que vous vous prenez pour un hacker cool, écrivez en assembleur, ou alors restez à l'écart et laissez le compilateur faire son travail.

 
Aleksandr Matveev:

Dans cet exemple, tout le corps de votre boucle aurait pu être supprimé grâce à l'optimisation.

Le résultat de l'exécution avec un corps de boucle vide, très différent, fonctionne beaucoup plus rapidement.

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

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

En général, tout se passe comme prévu, il n'est pas nécessaire de faire des bêtises, de chercher des problèmes inexistants et de créer des problèmes réels.

Si cela vous démange et que vous pensez être un hacker cool, écrivez en assembleur, sinon restez à l'écart et laissez le compilateur faire son travail.

Le principal problème est précisément que je ne me considère pas comme un coolhacker. C'est pourquoi, à mon avis, les variables doivent être déclarées en dehors de la boucle. Et mieux encore - au début de la fonction, d'un seul coup.

Et juste les koolhousers peuvent déclarer des variables selon les besoins, à l'intérieur du code.

 
Georgiy Merts:

Le principal problème est précisément que je ne me considère pas comme un coolhacker. C'est pourquoi, à mon avis, les variables doivent être déclarées en dehors de la boucle. Et de préférence au début de la fonction, en une seule fois.

Les koolhackers peuvent déclarer des variables selon leurs besoins dans le code.

Je préfère décomposer mon code en blocs logiques et déclarer les variables nécessaires dans ces blocs plutôt que de créer un tas de variables au début d'une fonction, dont la plupart ne sont nécessaires que dans un seul bloc, quelque part loin en dessous