2016-01-06 1 views
2

Parfois, je déclare des variables "à usage unique" dans mon code pour plus de clarté. Est-ce que cela affecte considérablement les performances ou est-ce que le compilateur peut l'optimiser?Les déclarations de variables devraient-elles toujours être évitées en C++?

Par exemple, je aurais tendance à faire:

int minVal = long_arithmetic_expresion(); 
int maxVal = even_longer_expression(); 

for (int i = minVal; i < maxVal; i++) 
    { 
     // Do stuff not related to minVal or maxVal 
    } 

double part1 = 4*sqrt(something)* ... // Very long thing 
double part2 = 5*sqrt(something else)* ... // Very long thing 

double interestingValue = part1/part2; // This is the only interesting variable for later 

Plutôt que:

for (int i = long_arithmetic_expresion(); i < even_longer_expression(); i++) 
    { 
     // Do stuff not related to minVal or maxVal 
    } 

double interestingValue = (4*sqrt(whatever)* ...)/(5*sqrt(something else)* ...); 

Cette boucle serait contenue dans une fonction qui sera appelée à plusieurs reprises, de sorte que même les performances des petites le gain serait pertinent dans mon cas.

Note:

Comme il a été rapidement fait remarquer, il y a une chance que even_longer_expression() pourrait être évaluée à chaque étape de la boucle, ce qui est évidemment pas bon. Pour plus de clarté, ma question concerne le fait de déclarer des variables à usage unique. J'ai ajouté un peu plus de code après la boucle. Je me réfère à des cas comme les variables part1 et part2.

+0

Dans votre exemple 'int maxVal = even_longer_expression();' ne devrait être déclaré que – Evgeny

+3

'even_longer_expression()' va être évalué à chaque passage, donc bien sûr, il est logique de ne pas l'avoir. –

+1

'minVal' et' maxVal' devraient être 'const' ou même' constexpr' si c'est possible. Cela vous empêche non seulement de changer accidentellement leurs valeurs, mais vous aide aussi le compilateur à faire plus d'optimisations. –

Répondre

3

Est-ce que cela affecte considérablement les performances ou est-ce que le compilateur peut l'optimiser?

dépend totalement:

Si long_arithmetic_expresion() et even_longer_expression() sont marqués comme constexpr et non susceptible de changer au cours de l'exécution, le compilateur peut optimiser des appels récurrents à ces fonctions.

Sinon, il pourrait être préférable d'utiliser les variables initialisées une fois.

+0

Faire 'maxVal' a' const' en plus. Ceci, alors, est aussi le style traditionnellement vu avec les fins de l'itérateur. Cela évite de réévaluer facilement chaque itération de la boucle 'for'. – B98

+0

@ B98 En résumé, cela signifie-t-il qu'il n'y a pas de perte de performance dans la déclaration des variables supplémentaires si elles sont const, mais peut-être vaut-il mieux éviter les déclarations supplémentaires si elles ne sont pas const? – frischkase

+1

@frischkase Cela dépend du compilateur et des commutateurs, mais même si je pense que 'const' pourrait augmenter les chances de déclenchement de l'optimisation, ne pas déclarer une variable et mélanger beaucoup de code ressemble plutôt à une optimisation prématurée. Si nécessaire, seul le code de l'objet révélera les besoins réels, mais les optimiseurs actuels suivent les flux et optimisent. - Les variables 'const' et * introduisent des noms * qui peuvent exprimer l'intention, ou abréger, const en ajoutant la constance à le sens. Je pense que la performance n'est pas la question dominante dans ce cas, la logique et le style pourrait être. – B98

1

Sauf si vous désactivez les optimisations, les codes suivants seraient presque sûrement montrer absolument les mêmes performances sur un compilateur moderne (étant donné que les expressions sont évidemment indépendants):

// save to temporary minVal variable 
int minVal = long_arithmetic_expresion(); 
int maxVal = even_longer_expression(); 
for (int i = minVal; i < maxVal; i++) { 
    ... 
} 

// avoid creating temporary minVal variable 
int maxVal = even_longer_expression(); 
for (int i = long_arithmetic_expresion(); i < maxVal; i++) { 
    ... 
} 

Mais la première version est souvent plus lisible =) La raison est la suivante: copy propagation pour les variables de types fondamentaux est trivial à faire pour un compilateur. Donc, dans la première version du compilateur supprimerait i = minVal affectation.