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

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

ou

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

Y a-t-il une différence ? compte tenu de toutes les optimisations du compilateur mql5 ?

 
pivalexander:

ou

Y a-t-il une différence ? compte tenu de toutes les optimisations du compilateur mql5 ?

Il n'y a pas de différence dans la compilation, donc n'hésitez pas à utiliser la deuxième option.
 

Personnellement, je préfère le premier.

Juste au cas où. Le compilateur est peut-être assez intelligent pour ne pas allouer de la mémoire à chaque fois, mais dans le premier cas, je le spécifie explicitement, alors que dans le second cas, c'est un résultat implicite du compilateur, car la logique du langage est de créer une variable à l'intérieur d'un bloc et de la supprimer à la sortie du bloc.

Et assimiler int à string sans transformation est une mauvaise pratique.

 
pivalexander:

Y a-t-il une différence ? compte tenu de toutes les optimisations du compilateur mql5 ?

N'écoutez pas qu'il n'y a pas de différence. N'utilisez que la première option, il y a une différence. Je n'ai pas étudié le disassm de mcl cependant.

 
Georgiy Merts:

Personnellement, je préfère le premier.

Juste au cas où. Le compilateur peut être assez intelligent pour ne pas allouer de la mémoire à chaque fois, mais dans le premier cas je le spécifie explicitement, alors que dans le deuxième cas c'est un résultat implicite du compilateur, car la logique du langage est de créer une variable à l'intérieur d'un bloc, et à la sortie du bloc elle doit être supprimée.

Et assimiler int à string sans le convertir est une mauvaise pratique.

George a raison, ce n'est pas garanti.

Et nous obtenons une déformation de la conversion implicite de "nombre" à "chaîne".


Et c'est exactement comme cela que nous nous débarrassons de l'indétermination et de la déformation.

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

Personnellement, je préfère le premier.

Juste au cas où. Le compilateur peut être assez intelligent pour ne pas allouer de la mémoire à chaque fois, mais dans le premier cas je le spécifie explicitement, alors que dans le second cas c'est un résultat implicite du travail du compilateur

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

p.s. Peut-être que j'étais un peu excité par la trivialité dans le cas d'un tampon de chaîne. 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
 

Ne les écoutez pas, ils vous en diront long sur ce sujet ici :))

// c++
#include <iostream>
#include <string>
using namespace std;

void* operator new(size_t sz) {
    void *ptr = std::malloc(sz);
    if (ptr)
        return ptr;
    else
        throw std::bad_alloc{};
}


int main() {
        for (uint i = 0;  i < 3;  ++ i) {
                string s;
                char buf[10];
                sprintf(buf, "%u", i);
                s = "sfjhidfsrtea111";
                s += buf;
                cout << s << '\n';
        }
}

Je compile gcc -O3, je l'exécute sous le débogueur, je place un point d'arrêt sur l'opérateur new, j'obtiens trois appels. La même chose avec clang.

Note : si la chaîne est retirée de la boucle, je reçois un appel.

 
Alexey Navoykov:

Vous plaisantez ? C'est une situation tellement triviale pour un compilateur qu'il n'y a rien à dire. Si vous êtes si paranoïaque, vous pouvez écrire du code purement en assembleur. Mais même cela devient insensé de nos jours. Vous devrez faire de gros efforts pour battre l'optimisation des compilateurs modernes.

p.s. Peut-être que j'étais un peu excité par la trivialité dans le cas d'un tampon de chaîne. 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

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.

Ce n'est pas une question d'efficacité (les compilateurs modernes donnent vraiment un code de très haute qualité) mais de schéma de pensée du programmeur. Quand je regarde le code source de Kodobase, je me demande souvent combien de petits défauts simples mais potentiellement dangereux ils contiennent. Dans ce cas, ce n'est pas encore très critique, le maximum qui puisse arriver est que le programme fonctionne un peu plus lentement. Les erreurs réelles peuvent être beaucoup plus délicates.

 
Vict:

Ne les écoutez pas, ils vous en diront long sur ce sujet ici :))

Je compile gcc -O3, je l'exécute sous le débogueur, je place un point d'arrêt sur l'opérateur new, j'obtiens trois appels. La même chose avec clang.

Donc, si la chaîne est retirée de la boucle, je reçois un appel.

Il n'aurait pas pu faire autrement car vous avez vous-même interféré avec l'optimisation par des points d'arrêt. L'essence de l'optimisation est qu'elle ne doit pas changer la logique de l'algorithme. C'est pourquoi il ne peut pas être détecté explicitement. S'il y a un point d'arrêt à cet endroit, le compilateur n'a évidemment pas le droit de couper ce code. Vous pensiez que le compilateur pouvait sauter par-dessus le point d'arrêt? )

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

 
En attendant les mesures)
 
Alexey Navoykov:

Il ne pourrait pas faire autrement car vous avez vous-même interféré avec l'optimisation par des points d'arrêt. L'intérêt de l'optimisation est qu'elle ne doit pas changer la logique de l'algorithme. C'est pourquoi il ne peut pas être détecté explicitement. S'il y a un point d'arrêt à cet endroit, le compilateur n'a naturellement pas le droit de couper ce code. Vous attendiez-vous à ce que le compilateur saute par-dessus le point d'arrêt ? )

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

Mec, c'est juste une stupidité sauvage, qu'est-ce qu'il y a à commenter, une incompréhension totale de la façon dont le débogueur fonctionne.

A propos de la vitesse - le gestionnaire de mémoire n'est pas si bête, et pas le fait qu'il va demander au système d'exploitation, peut surutiliser plus tôt alloué. En général, utilisez-le comme vous le souhaitez, c'est vous qui décidez. Mais vous ne devez pas en convaincre les autres, du moins jusqu'à ce que vous fournissiez des preuves concrètes, où sont-elles ?