web-dev-qa-db-fra.com

La const-correct peut-elle améliorer les performances?

J'ai lu à plusieurs reprises que l'application de const-correctness dans votre code C ou C++ n'est pas seulement une bonne pratique en matière de maintenabilité, mais elle peut également permettre à votre compilateur d'effectuer des optimisations. Cependant, j'ai également lu l'opposé complet - cela n'affecte pas du tout les performances.

Par conséquent, avez-vous des exemples où l'exactitude de const peut aider votre compilateur à améliorer les performances de votre programme?

82
shuhalo

const l'exactitude ne peut pas améliorer les performances car const_cast et mutable sont dans le langage, et permettent au code d'enfreindre les règles en conformité. Cela devient encore pire en C++ 11, où vos données const peuvent par exemple être un pointeur vers un std::atomic, ce qui signifie que le compilateur doit respecter les modifications apportées par d'autres threads.

Cela dit, il est trivial pour le compilateur de regarder le code qu'il génère et de déterminer s'il écrit réellement dans une variable donnée, et d'appliquer les optimisations en conséquence.

Cela dit, const l'exactitude est une chose bonne en ce qui concerne la maintenabilité. Sinon, les clients de votre classe pourraient casser les membres internes de cette classe. Par exemple, considérez la std::string::c_str() standard - si elle ne pouvait pas retourner une valeur const, vous seriez en mesure de visser avec le tampon interne de la chaîne!

N'utilisez pas const pour des raisons de performances. Utilisez-le pour des raisons de maintenabilité.

61
Billy ONeal

Oui il peut.

La plupart des const sont purement à l’intention du programmeur et n’aident pas le compilateur à optimiser car il est légal de les rejeter et ils ne disent donc rien au compilateur pour l’optimisation. Cependant, certains const ne peuvent pas être (légalement) supprimés et ceux-ci fournissent au compilateur des informations utiles pour l'optimisation.

Par exemple, l'accès à une variable globale définie avec un type const peut être inséré tandis que celui sans type const ne peut pas être inséré car il peut changer au moment de l'exécution.

https://godbolt.org/g/UEX4NB

C++:

int foo1 = 1;
const int foo2 = 2;

int get_foo1() {
    return foo1;
}

int get_foo2() {
    return foo2;
}

asm:

foo1:
        .long   1
foo2:
        .long   2
get_foo1():
        Push    rbp
        mov     rbp, rsp
        mov     eax, DWORD PTR foo1[rip] ; foo1 must be accessed by address
        pop     rbp
        ret
get_foo2():
        Push    rbp
        mov     rbp, rsp
        mov     eax, 2 ; foo2 has been replaced with an immediate 2
        pop     rbp
        ret

En termes pratiques, gardez à l'esprit que si const peut améliorer les performances, dans la plupart des cas, ce ne sera pas le cas, mais le changement ne sera pas perceptible. L'utilité première de const n'est pas l'optimisation.


Steve Jessop donne un autre exemple dans son commentaire sur la question originale qui soulève quelque chose qui mérite d'être mentionné. Dans une portée de bloc, il est possible pour un compilateur de déduire si une variable sera mutée et d'optimiser en conséquence, indépendamment de const, car le compilateur peut voir toutes les utilisations de la variable. En revanche, dans l'exemple ci-dessus, il est impossible de prédire si foo1 sera muté car il pourrait être modifié dans d'autres unités de traduction. Je suppose qu'un ultra-compilateur sensible hypothétique pourrait analyser un programme entier et déterminer s'il est valide pour l'accès en ligne à foo1... mais pas les vrais compilateurs.

21
Praxeolitic

d'après mon expérience, non

Pour les variables scalaires, le compilateur est capable de déterminer chaque fois que la valeur est modifiée et d'effectuer lui-même l'optimisation nécessaire.

Pour les pointeurs de tableau, l'exactitude de const n'est pas une garantie que les valeurs sont vraiment constantes en présence de problèmes d'alias potentiels. Par conséquent, le compilateur ne peut pas utiliser le modificateur const seul pour effectuer des optimisations

si vous cherchez une optimisation, vous devriez considérer __restrict__ ou des modificateurs/attributs de fonctions spéciales: http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

6
Anycorn
5
Maxim Egorushkin