Non, mais oui, mais peut-être, mais peut-être dans l'autre sens, mais non.
Comme les gens l'ont déjà souligné (en supposant un langage où l'addition est associative à gauche, comme C, C ++, C # ou Java), l'expression ((1 + 2) + 3)
est exactement équivalente à 1 + 2 + 3
. Ce sont différentes façons d'écrire quelque chose dans le code source, qui n'auraient aucun effet sur le code machine ou le code d'octet résultant.
Dans les deux cas, le résultat sera une instruction pour, par exemple, ajouter deux registres, puis ajouter un troisième, ou prendre deux valeurs dans une pile, l'ajouter, la repousser, puis la prendre et une autre et les ajouter, ou ajouter trois registres dans une seule opération, ou une autre façon de additionner trois nombres en fonction de ce qui est le plus sensible au niveau suivant (le code machine ou le code octet). Dans le cas du code d'octet, celui-ci subira probablement à son tour une restructuration similaire en ce que, par exemple, l'équivalent IL de celui-ci (qui serait une série de charges dans une pile, et des paires éclatées pour ajouter puis repousser le résultat) n'entraînerait pas une copie directe de cette logique au niveau du code machine, mais quelque chose de plus sensé pour la machine en question.
Mais il y a quelque chose de plus à votre question.
Dans le cas de n'importe quel compilateur sain C, C ++, Java ou C #, je m'attendrais à ce que le résultat des deux instructions que vous donnez ait exactement les mêmes résultats que:
int a = 6;
Pourquoi le code résultant devrait-il perdre du temps à faire des calculs sur les littéraux? Aucun changement à l'état du programme arrêteront le résultat d' 1 + 2 + 3
être 6
, de sorte que ce qui devrait aller dans le code en cours d' exécution. En effet, peut-être même pas cela (selon ce que vous faites avec ce 6, nous pouvons peut-être tout jeter; et même C # avec sa philosophie de "ne pas optimiser fortement, car la gigue optimisera cela de toute façon" produira l'équivalent deint a = 6
ou jetez le tout comme inutile).
Cela nous amène cependant à une éventuelle extension de votre question. Considérer ce qui suit:
int a = (b - 2) / 2;
/* or */
int a = (b / 2)--;
et
int c;
if(d < 100)
c = 0;
else
c = d * 31;
/* or */
int c = d < 100 ? 0 : d * 32 - d
/* or */
int c = d < 100 && d * 32 - d;
/* or */
int c = (d < 100) * (d * 32 - d);
(Remarque, ces deux derniers exemples ne sont pas valides en C #, alors que tout le reste est ici, et ils sont valides en C, C ++ et Java.)
Ici encore, nous avons un code exactement équivalent en termes de sortie. Comme ce ne sont pas des expressions constantes, elles ne seront pas calculées au moment de la compilation. Il est possible qu'une forme soit plus rapide qu'une autre. Lequel est plus vite? Cela dépendrait du processeur et peut-être de certaines différences d'état plutôt arbitraires (d'autant plus que si l'un est plus rapide, il est peu probable qu'il soit beaucoup plus rapide).
Et ils ne sont pas entièrement sans rapport avec votre question, car ils concernent principalement des différences dans l'ordre dans lequel quelque chose est conceptuellement fait.
Dans chacun d'eux, il y a une raison de soupçonner que l'un peut être plus rapide que l'autre. Les décrémentations simples peuvent avoir une instruction spécialisée, donc (b / 2)--
pourraient en effet être plus rapides que (b - 2) / 2
. d * 32
pourrait peut-être être produit plus rapidement en le transformant en d << 5
rendant ainsi d * 32 - d
plus rapide qued * 31
. Les différences entre les deux derniers sont particulièrement intéressantes; l'un permet de sauter certains traitements dans certains cas, mais l'autre évite la possibilité d'une mauvaise prédiction de branchement.
Donc, cela nous laisse avec deux questions: 1. L'un est-il réellement plus rapide que l'autre? 2. Un compilateur convertira-t-il le plus lent en le plus rapide?
Et la réponse est 1. Cela dépend. 2. Peut-être.
Ou pour étendre, cela dépend car cela dépend du processeur en question. Il y a certainement eu des processeurs où l'équivalent naïf de code machine de l'un serait plus rapide que l'équivalent naïf de code machine de l'autre. Au cours de l'histoire de l'informatique électronique, il n'y en a pas eu un qui a toujours été le plus rapide non plus (l'élément de prédiction erronée des branches en particulier n'était pas pertinent pour beaucoup lorsque les processeurs non pipelinés étaient plus courants).
Et peut-être, parce qu'il y a un tas d'optimisations différentes que les compilateurs (et la gigue et les moteurs de script) feront, et bien que certains puissent être obligatoires dans certains cas, nous serons généralement en mesure de trouver des morceaux de code logiquement équivalent qui même le compilateur le plus naïf a exactement les mêmes résultats et quelques morceaux de code logiquement équivalent où même le plus sophistiqué produit un code plus rapide pour l'un que pour l'autre (même si nous devons écrire quelque chose de totalement pathologique juste pour prouver notre point).
Cela peut sembler être une toute petite préoccupation d'optimisation,
Non. Même avec des différences plus compliquées que celles que je donne ici, cela semble être une préoccupation absolument minuscule qui n'a rien à voir avec l'optimisation. En fait, c'est une question de pessimisation, car vous pensez que le plus difficile à lire ((1 + 2) + 3
pourrait être plus lent que le plus facile à lire 1 + 2 + 3
.
mais choisir C ++ plutôt que C # / Java / ... est une question d'optimisations (IMHO).
Si c'est vraiment de cela qu'il s'agissait de choisir C ++ plutôt que C # ou Java, je dirais que les gens devraient graver leur copie de Stroustrup et ISO / IEC 14882 et libérer de l'espace de leur compilateur C ++ pour laisser de la place pour d'autres MP3 ou quelque chose.
Ces langues ont des avantages différents les unes par rapport aux autres.
L'un d'eux est que C ++ est toujours généralement plus rapide et plus léger lors de l'utilisation de la mémoire. Oui, il existe des exemples où C # et / ou Java sont plus rapides et / ou ont une meilleure utilisation de la mémoire pendant la durée de vie des applications, et ceux-ci deviennent de plus en plus courants à mesure que les technologies impliquées s'améliorent, mais nous pouvons toujours nous attendre à ce que le programme moyen écrit en C ++ soit un exécutable plus petit qui fait son travail plus rapidement et utilise moins de mémoire que l'équivalent dans l'un de ces deux langages.
Ce n'est pas de l'optimisation.
Optimisation est parfois utilisée pour signifier "accélérer les choses". C'est compréhensible, car souvent, lorsque nous parlons vraiment d '"optimisation", nous parlons en effet d'accélérer les choses, et donc l'un est devenu un raccourci pour l'autre et j'avoue que j'utilise le mot de cette façon moi-même.
Le mot correct pour "accélérer les choses" n'est pas optimisation . Le mot correct ici est amélioration . Si vous apportez une modification à un programme et que la seule différence significative est qu'il est maintenant plus rapide, il n'est en aucun cas optimisé, c'est juste mieux.
L'optimisation est lorsque nous apportons une amélioration en ce qui concerne un aspect particulier et / ou un cas particulier. Des exemples courants sont:
- C'est maintenant plus rapide pour un cas d'utilisation, mais plus lent pour un autre.
- C'est maintenant plus rapide, mais utilise plus de mémoire.
- Il est maintenant plus léger en mémoire, mais plus lent.
- C'est maintenant plus rapide, mais plus difficile à entretenir.
- Il est maintenant plus facile à entretenir, mais plus lent.
De tels cas seraient justifiés si, par exemple:
- Le cas d'utilisation plus rapide est plus courant ou plus gravement entravé au départ.
- Le programme était trop lent et nous avons beaucoup de RAM libre.
- Le programme était à l'arrêt car il utilisait tellement de RAM qu'il passait plus de temps à échanger qu'à exécuter son traitement ultra-rapide.
- Le programme était trop lent et le code plus difficile à comprendre est bien documenté et relativement stable.
- Le programme est toujours assez rapide, et la base de code plus compréhensible est moins chère à entretenir et permet d'autres améliorations à apporter plus facilement.
Mais, de tels cas ne seraient pas non plus justifiés dans d'autres scénarios: le code n'a pas été amélioré par une mesure de qualité infaillible absolue, il a été amélioré à un égard particulier qui le rend plus adapté à un usage particulier; optimisé.
Et le choix de la langue a un effet ici, car la vitesse, l'utilisation de la mémoire et la lisibilité peuvent toutes en être affectées, mais la compatibilité avec d'autres systèmes, la disponibilité des bibliothèques, la disponibilité des temps d'exécution, la maturité de ces temps d'exécution sur un système d'exploitation donné peuvent également en être affectés. (Pour mes péchés, j'ai en quelque sorte fini par avoir Linux et Android comme mon système d'exploitation préféré et C # comme mon langage préféré, et même si Mono est génial, mais je me heurte toujours assez à celui-ci).
Dire "choisir C ++ plutôt que C # / Java / ... est une question d'optimisation" n'a de sens que si vous pensez que C ++ est vraiment nul, car l'optimisation est à propos de "mieux malgré ..." et non "mieux". Si vous pensez que le C ++ est meilleur malgré lui, alors la dernière chose dont vous avez besoin est de vous inquiéter des micro-opts possibles aussi minuscules. En effet, vous feriez probablement mieux de l'abandonner du tout; les hackers heureux sont aussi une qualité à optimiser!
Si toutefois, vous êtes enclin à dire "j'aime le C ++, et l'une des choses que j'aime à ce sujet, c'est d'éliminer les cycles supplémentaires", alors c'est une autre affaire. Il est toujours vrai que les micro-opérations ne valent la peine que si elles peuvent être une habitude réflexive (c'est-à-dire que la façon dont vous avez tendance à coder naturellement sera plus rapide plus souvent que lente). Sinon, ce n'est même pas une optimisation prématurée, c'est une pessimisation prématurée qui ne fait qu'empirer les choses.