OVH Cloud OVH Cloud

Déclaration dans ou hors boucle ?

7 réponses
Avatar
Frédéric LAMBOUR
Question basique pour l'optimisation du code

Qd on a besoin de variable dans une boucle (string, intn objet ect ...) doit
on les déclarer dans la boucle ou hors de la boucle ?

Exemple :
while(bTest)

{

string stest;

//...

}



ou

string stest

while(bTest)

{

string stest;

//...

}

7 réponses

Avatar
ByB
Dans son message précédent, Frédéric LAMBOUR a écrit :
Question basique pour l'optimisation du code

Qd on a besoin de variable dans une boucle (string, intn objet ect ...) doit
on les déclarer dans la boucle ou hors de la boucle ?

Exemple :
while(bTest)

{

string stest;

//...

}



ou

string stest

while(bTest)

{

string stest;

//...

}




A mon avis, moins il y a à faire dans la boucle, et plus elle tourne
vite. Donc je conseillerais de faire les déclarations en dehors, plutôt
que des les répéter n fois ...
Par ailleurs, votre 2ème exemple a un problème (de copier/coller) car
stest est définie deux fois (hors, puis dans la boucle)

--
Ceci est une signature automatique de MesNews.
Site : http://www.mesnews.net
Avatar
De Simone Alessandro
Frédéric LAMBOUR wrote:
Question basique pour l'optimisation du code

Qd on a besoin de variable dans une boucle (string, intn objet ect ...) doit
on les déclarer dans la boucle ou hors de la boucle ?

Exemple :
while(bTest)

{

string stest;

//...

}



ou

string stest

while(bTest)

{

string stest;

//...

}





chaque fois que tu déclares une variable, normalement un push sur le
stack est fait (la valeur pushée est une référence vers un objet ou une
valeur). Sauf si le compilo fait l'optimisation, normalement à la fin du
scope de la variable (ici la fin du tour de boucle) la valeur est popée
du stack. Donc dans ton cas il est préférable de déclarer toutes tes
variables juste avant ta boucle sinon elles seront pushée popées
inutilement x fois.

--
Alessandro De Simone
email : (remove ".IHATESPAM")

Win32
Avatar
Frédéric LAMBOUR
Logique

"De Simone Alessandro" a écrit dans le
message de news:
Frédéric LAMBOUR wrote:
> Question basique pour l'optimisation du code
>
> Qd on a besoin de variable dans une boucle (string, intn objet ect ...)


doit
> on les déclarer dans la boucle ou hors de la boucle ?
>
> Exemple :
> while(bTest)
>
> {
>
> string stest;
>
> //...
>
> }
>
>
>
> ou
>
> string stest
>
> while(bTest)
>
> {
>
> string stest;
>
> //...
>
> }
>
>

chaque fois que tu déclares une variable, normalement un push sur le
stack est fait (la valeur pushée est une référence vers un objet ou une
valeur). Sauf si le compilo fait l'optimisation, normalement à la fin du
scope de la variable (ici la fin du tour de boucle) la valeur est popée
du stack. Donc dans ton cas il est préférable de déclarer toutes tes
variables juste avant ta boucle sinon elles seront pushée popées
inutilement x fois.

--
Alessandro De Simone
email : (remove ".IHATESPAM")

Win32


Avatar
Sylvain Collange
Frédéric LAMBOUR a écrit :
Question basique pour l'optimisation du code

Qd on a besoin de variable dans une boucle (string, intn objet ect
...) doit on les déclarer dans la boucle ou hors de la boucle ?



Si tu n'en a pas besoin hors de la boucle, ne la déclare pas hors de la
boucle. Plus la portée d'une variable est courte (locale) mieux ça vaut.

Au niveau efficacité, ça ne change strictement rien. Du moins, tant
qu'il ne s'agit que d'une déclaration sans affectation ni new.
Un bon moyen de vérifier est de faire le test, sur un grand nombre
d'itérations.

Ou alors regarder le code IL généré et s'apercevoir que c'est exactement
le même dans les deux cas (l'IL n'a pas de notion de variable locale à
un bloc de code).

--
Sylvain Collange
Avatar
Bruno Jouhier [MVP]
> chaque fois que tu déclares une variable, normalement un push sur le stack
est fait (la valeur pushée est une référence vers un objet ou une valeur).
Sauf si le compilo fait l'optimisation, normalement à la fin du scope de
la variable (ici la fin du tour de boucle) la valeur est popée du stack.
Donc dans ton cas il est préférable de déclarer toutes tes variables juste
avant ta boucle sinon elles seront pushée popées inutilement x fois.



N'importe quel compilateur décent va gérer ça plus efficacement. Au lieu de
réserver l'espace sur le stack à chaque variable, il va calculer la taille
maximale utilisée par les variables dans les divers chemins (en décomptant
les variables qu'il décidera de garder en registre), et il allouera ça
globalement à l'entrée de la méthode (et le pop sera géré par le retour de
méthode). Par conséquent, le fait de déclarer (je dis bien déclarer, pas
initialiser) la variable à l'extérieur ou à l'intérieur de la boucle n'aura
aucun impact sur les perfs.

Une fois qu'on a compris que les perfs ne seront pas affectées, ça devient
une question de style. AMA, il faut essayer de limiter la visibilité des
variables au fragment de code où elles sont utilisées (comme ça, celui qui
revient sur le code plus tard n'a pas besoin de trop chercher où la variable
est utilisée). Et donc la version avec la déclaration à l'intérieur est
préférable.

Bruno.


--
Alessandro De Simone
email : (remove ".IHATESPAM")

Win32


Avatar
De Simone Alessandro
Bruno Jouhier [MVP] a écrit :

N'importe quel compilateur décent va gérer ça plus efficacement. Au lieu de
réserver l'espace sur le stack à chaque variable, il va calculer la taille
maximale utilisée par les variables dans les divers chemins (en décomptant
les variables qu'il décidera de garder en registre), et il allouera ça
globalement à l'entrée de la méthode (et le pop sera géré par le retour de
méthode). Par conséquent, le fait de déclarer (je dis bien déclarer, pas
initialiser) la variable à l'extérieur ou à l'intérieur de la boucle n'aura
aucun impact sur les perfs.



100% d'accord, on parle bien d'une optimisation (banale tu diras) :-)

Une fois qu'on a compris que les perfs ne seront pas affectées, ça devient
une question de style. AMA, il faut essayer de limiter la visibilité des
variables au fragment de code où elles sont utilisées (comme ça, celui qui
revient sur le code plus tard n'a pas besoin de trop chercher où la variable
est utilisée). Et donc la version avec la déclaration à l'intérieur est
préférable.



Même dans le cas non optimisé que j'ai cité, je dirais que cela n'a pas
un gros impact sur les performances dans le sens ou une allocation sur
le stack n'est qu'une incrémentation de pointeur.
Et je suis tout à fait d'accord que le reste est une question de style.

Bonne soirée,

--
Alessandro De Simone
email : (remove ".IHATESPAM")

Win32
Avatar
Bruno Jouhier [MVP]
> Même dans le cas non optimisé que j'ai cité, je dirais que cela n'a pas un
gros impact sur les performances dans le sens ou une allocation sur le
stack n'est qu'une incrémentation de pointeur.



Tout à fait, c'est même une simple incrémentation de registre et donc une
simple instruction très rapide.

Aussi, il est "en général" inutile de se focaliser sur des
micro-optimisations de ce style (faut-il que je déclare à l'extérieur ou à
l'intérieur de la boucle, faut-il que j'utilise un foreach ou un for avec un
index explicite, etc.). Il faut choisir les bonnes structures de données,
les bons algorithmes, et privilégier la clarté du style (en pensant à celui
qui relira plus tard) à des micro-optimisations qui rendraient le code plus
complexe. L'optimisation de perf, ça se fait a posteriori, avec un profiler.

Bruno.

Et je suis tout à fait d'accord que le reste est une question de style.

Bonne soirée,

--
Alessandro De Simone
email : (remove ".IHATESPAM")

Win32