Le compilateur C# lui-même ne modifie pas le émise IL beaucoup dans la version Release. Notable est qu'il ne diffuse plus le NOP opcodes qui vous permettent de définir un point d'arrêt sur une accolade. Le grand est à l'optimiseur qui est intégrée dans le compilateur JIT. Je sais que ça fait les optimisations suivantes:
Méthode inline. Un appel de méthode est remplacé par l'injection du code de la méthode. C'est grand, il fait accesseurs de propriété essentiellement gratuit.
PROCESSEUR d'allocation de registres. Les variables locales et les arguments de méthode peut rester stocké dans un PROCESSEUR inscrire sans jamais (ou moins souvent) d'être stockés sur le frame de pile. C'est un gros, notables pour faire le débogage de code optimisé si difficile. Et de donner le volatile mot un sens.
Index de tableau de vérification de l'élimination. Une importante optimisation lorsque l'on travaille avec des tableaux (de tous .Collecte NETTE des classes de l'utilisation d'un tableau à l'interne). Lorsque le compilateur JIT peut vérifier qu'une boucle ne jamais les indices d'un tableau en dehors des limites ensuite, il permettra d'éliminer l'indice de la case. Big one.
Déroulement de la boucle. Boucles courtes (jusqu'à 4) avec les petits organismes sont éliminés en répétant le code dans le corps de la boucle. Évite les erreurs de prédiction de la direction générale de la peine.
L'élimination du code mort. Une instruction if (false) { /.../ } obtient complètement éliminé. Cela peut se produire en raison de constantes et inline. D'autres cas où le compilateur JIT peut déterminer que le code n'a pas de possibles effets secondaires. Cette optimisation est ce qui rend le profilage de code si délicate.
Code de levage. Code à l'intérieur d'une boucle qui n'est pas affecté par la boucle peut être déplacé hors de la boucle.
Commune de la sous-expression de l'élimination. x = y + 4; z = y + 4; devient z = x;
De constantes. x = 1 + 2; devient x = 3; Ce simple exemple est pris tôt par le compilateur, mais il arrive à temps JIT, quand d'autres optimisations de rendre cela possible.
Copie de propagation. x = a; y = x; devient y = a; Cela permet à l'allocateur de registres de prendre de meilleures décisions. C'est un gros problème dans le x86 gigue parce qu'il a si peu de registres de travailler avec. Avoir de sélectionner les plus appropriés est essentiel pour la perf.
Elles sont très importantes optimisations qui peuvent faire une grande différence lorsque, par exemple, vous le profil de la version de Débogage de votre application et de le comparer à la Version de publication. Que seul importe vraiment bien que lorsque le code est sur votre chemin critique, de 5 à 10% de la code que vous écrivez qu' en réalité affecte la perf de votre programme. L'équipe de l'optimiseur n'est pas assez intelligent pour savoir à l'avance ce qui est crucial, il ne peut appliquer que le "tourner à onze" l'accès pour tous le code.
Le résultat de ces optimisations sur votre programme du temps d'exécution est souvent affectée par le code qui fonctionne ailleurs. La lecture d'un fichier, l'exécution d'une requête de dbase, etc. Faire le travail de l'équipe optimizer n'est complètement invisible. Il n'a pas l'esprit bien :)
L'équipe de l'optimiseur est assez fiable des codes, principalement parce qu'il a été mis à l'épreuve des millions de fois. Il est extrêmement rare d'avoir des problèmes dans la version Release de la version de votre programme. Il arrive cependant. À la fois le x64 et x86 frousse ont eu des problèmes avec des structures. Le x86 gigue a de la difficulté à virgule flottante de la cohérence, de la production subtilement des résultats différents lorsque les intermédiaires de virgule flottante de calcul sont conservés dans un FPU s'inscrire à 80 bits de précision au lieu de se tronquée vidés de la mémoire.