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

 
Georgiy Merts:

Non, je ne le suis pas.

Il est certain qu'un compilateur normal, dans ce cas, devrait faire ressortir une déclaration de variable à l'intérieur d'une boucle.

Je pense simplement qu'il faut toujours faire confiance au compilateur et à soi-même. Selon une norme de compilation, une variable locale est créée lorsqu'elle est déclarée et est supprimée à la sortie du bloc dans lequel elle a été déclarée. Vous devez donc vous concentrer sur ce principe en premier lieu et ne pas attendre que le compilateur améliore votre code pour vous.

Donc je dis que si vous voulez "faire mieux", allez à l'assembleur, si vous avez besoin de 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 ou non dégénéré une méthode virtuelle particulière en un appel régulier, ou s'il a coupé une vérification de pointeur inutile... Que pouvez-vous faire dans un MQL géré avec une telle paranoïa ? )

Et modifier le code pour l'adapter 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 exactement de correction du code. La variable doit être déclarée directement dans le bloc dans lequel elle est utilisée.

 
Vict:

Mec, c'est juste follement stupide, qu'est-ce qu'il y a à commenter, un manque total de compréhension de la façon dont le débogueur fonctionne.

Vous le faites.
 
Alexey Navoykov:
Vous le faites.

Comme au jardin d'enfants ;))) Je m'explique pour ceux qui sont dans la cuve : d'abord on compile g++ 1.cpp, il n'y a pas de points d'arrêt, le compilateur n'en sait rien. Puis lancez le débogueur : gdb a.out, et seulement maintenant mettez un point d'arrêt.

Tu comprends les bêtises que tu as dites ?

 
Alexey Navoykov:

Vous ne pouvez détecter l'optimisation qu'en compilant le code ou en mesurant ses performances. C'est la première chose à faire. Et calmez-vous)

2019.08.18 10:28:12.826 SpeedTest (EURUSD,H1) 1. s1=rand() : loops=100000000 ms=7031

2019.08.18 10:28:19.885 SpeedTest (EURUSD,H1) 2. s2=rand() : loops=100000000 ms=7063

2019.08.18 10:28:27.037 SpeedTest (EURUSD,H1) 3. s3=rand() : loops=100000000 ms=7140

2019.08.18 10:28:34.045 SpeedTest (EURUSD,H1) 4. s4=rand() : loops=100000000 ms=7016

2019.08.18 10:28:41.135 SpeedTest (EURUSD,H1) 5. s5=rand() : loops=100000000 ms=7094

2019.08.18 10:28:47.896 SpeedTest (EURUSD,H1) 1. q=rand() : loops=100000000 ms=6750

2019.08.18 10:28:54.659 SpeedTest (EURUSD,H1) 2. q=rand() : loops=100000000 ms=6765

2019.08.18 10:29:01.447 SpeedTest (EURUSD,H1) 3. q=rand() : loops=100000000 ms=6797

2019.08.18 10:29:08.257 SpeedTest (EURUSD,H1) 4. q=rand() : loops=100000000 ms=6797

2019.08.18 10:29:15.102 SpeedTest (EURUSD,H1) 5. q=rand() : loops=100000000 ms=6844

//+------------------------------------------------------------------+
//|                                                    SpeedTest.mq5 |
//|                                                            IgorM |
//|                              https://www.mql5.com/ru/users/igorm |
//+------------------------------------------------------------------+
#property copyright "IgorM"
#property link      "https://www.mql5.com/ru/users/igorm"
#property version   "1.00"
#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; srand(GetTickCount()); test(N,"1. s1=rand()",s1=IntegerToString(rand()));
   string s2; srand(GetTickCount()); test(N,"2. s2=rand()",s2=IntegerToString(rand()));
   string s3; srand(GetTickCount()); test(N,"3. s3=rand()",s3=IntegerToString(rand()));
   string s4; srand(GetTickCount()); test(N,"4. s4=rand()",s4=IntegerToString(rand()));
   string s5; srand(GetTickCount()); test(N,"5. s5=rand()",s5=IntegerToString(rand()));

   srand(GetTickCount()); test(N,"1. q=rand()",string q=IntegerToString(rand()));
   srand(GetTickCount()); test(N,"2. q=rand()",string q=IntegerToString(rand()));
   srand(GetTickCount()); test(N,"3. q=rand()",string q=IntegerToString(rand()));
   srand(GetTickCount()); test(N,"4. q=rand()",string q=IntegerToString(rand()));
   srand(GetTickCount()); test(N,"5. q=rand()",string q=IntegerToString(rand()));
  }
//+------------------------------------------------------------------+
 
J'ai creusé sous le débogueur pour trouver un code similaire, mais sans opérateur utilisateur nouveau, eh bien, il pourrait y avoir quelques doutes - l'opérateur utilisateur n'est pas optimisé. Attrape un appel de malloc() de libc. Le résultat : chaîne en boucle - un appel avant chaque impression, hors boucle - un appel avant un lot d'impressions. Il n'y a pas de doute, seule la première variante est meilleure. Bien sûr, il est possible que quelque chose soit différent dans µl, mais il est préférable d'être guidé par des langages matures.
 
#define  N 9

2019.08.18 10:37:59.620 SpeedTest (EURUSD,H1) 1. s1=rand() : loops=1000000000 ms=70672

2019.08.18 10:39:10.352 SpeedTest (EURUSD,H1) 2. s2=rand() : loops=1000000000 ms=70719

2019.08.18 10:40:21.908 SpeedTest (EURUSD,H1) 3. s3=rand() : loops=1000000000 ms=71562

2019.08.18 10:41:32.315 SpeedTest (EURUSD,H1) 4. s4=rand() : loops=1000000000 ms=70407

2019.08.18 10:42:42.996 SpeedTest (EURUSD,H1) 5. s5=rand() : loops=1000000000 ms=70687

2019.08.18 10:43:50.964 SpeedTest (EURUSD,H1) 1. q=rand() : loops=1000000000 ms=67969

2019.08.18 10:44:58.887 SpeedTest (EURUSD,H1) 2. q=rand() : loops=1000000000 ms=67922

2019.08.18 10:46:06.829 SpeedTest (EURUSD,H1) 3. q=rand() : loops=1000000000 ms=67937

2019.08.18 10:47:14.602 SpeedTest (EURUSD,H1) 4. q=rand() : loops=1000000000 ms=67766

2019.08.18 10:48:22.428 SpeedTest (EURUSD,H1) 5. q=rand() : loops=1000000000 ms=67828

 

Igor Makanu:

#define    test(M,S,EX) {uint mss=GetTickCount();ulong nn=(ulong)pow(10,M);for(ulong tst=0;tst<nn&&!_StopFlag;tst++){EX;} \

Mec, la "barre d'espace" ne fonctionne pas pour toi ? Ce n'est pas la première fois que je remarque ça. Ou alors tu sauvegardes des octets sur ton disque dur ? )

 
Alexey Navoykov:

Vous plaisantez ? C'est une situation tellement triviale pour un compilateur qu'il n'y a rien à dire. Vous ne pouvez pas être si paranoïaque à ce sujet et vous contenter de coder en assembleur. ) Bien que même cela devienne insensé de nos jours. Vous devrez faire de gros efforts pour battre l'optimisation des compilateurs modernes.

p.s. Peut-être que j'ai été un peu excité par la trivialité ici parce que je parle de chaîne tampon. Mais il est garanti d'être sauvegardé dans MQL, non seulement à l'intérieur de la boucle mais même entre les appels de fonction. Ce sujet a été discuté ici plus d'une fois

J'ai le sentiment que l'auteur de cette déclaration ne sait pas du tout comment fonctionnent le processeur, la mémoire et le compilateur... Je parie que n'importe lequel de vos codes peut être accéléré au moins dix fois, voire des centaines de fois. À cause de ces codeurs de merde, la plupart des produits sont maintenant incroyablement lents sur des ordinateurs puissants dotés de dizaines de cœurs, alors qu'il suffit de réfléchir un peu... Mais certaines personnes pensent : "Pourquoi penser ? Vous devez coder..."

Pour votre information, aucun compilateur à l'heure actuelle n'a appris à comprendre ce que le programmeur voulait obtenir comme résultat. Il peut dérouler certaines boucles et optimiser certains accès à la mémoire pour conserver les données dans le cache du processeur, mais si le code n'a pas été optimisé au départ et qu'il est écrit à un seul endroit, aucun compilateur ne peut vous aider...

P.S. Lisez à loisir un livre divertissant de Chris Kaspersky"Program Optimization Technique. Utilisation efficace de la mémoire".

 
Alexey Volchanskiy:

Georges a raison, ce n'est pas garanti.

Et nous obtenons une conversion implicite déformante de 'nombre' à 'chaîne'.


Et c'est exactement comme ça qu'on se débarrasse de l'ambiguïté et de la distorsion.

for (int i = 0; i < 1000; i++)
   {
      static string st = IntegerToString(i);
      ...
   }

C'est comme ça que j'ai toujours fait.

string st = (string)i;

Et quel est l'intérêt de la statique ? L'affectation ne fonctionnera qu'une fois lors de la première itération.


J'ai décidé de mesurer la vitesse d'exécution.

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

Le résultat :

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

Exécuté plusieurs fois, le résultat est stable, le code avec la déclaration d'une variable après la boucle, fonctionne plus rapidement.

 
Alexey Navoykov:

Mec, la "barre d'espace" ne fonctionne pas pour toi ? Ce n'est pas la première fois que je remarque ça. Ou alors tu sauvegardes des octets sur ton disque dur ? )

Non, ce code n'est pas le mien, je l'ai un peu peaufiné - j'ai copié le code pour moi-même depuis le fil de discussion sur la "recherche de points-virgules" et je l'utilise pour les questions controversées, je suis trop paresseux pour le modifier,

J'ai des espaces et je suis trop paresseux pour le faire ))))

ZS : donnez-moi un code modèle, je le copierai sur moi, ce sera comme vous voulez dans le futur, je suis dans le principe, ça ne me dérange pas

ZS : ici AD :

#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);}
Raison: