Fonction ABS intégrale rapide
int X = a-b;
int d = Math.Abs(X);
Je suis assez sûr que .NET ne fait pas l'in-lining. Alors, vais-je faire si(), ou est-il quelques autres moins connus truc?
source d'informationauteur Daniel Mošmondor
Vous devez vous connecter pour publier un commentaire.
L'équipe effectue inline dans certaines circonstances. Je ne sais pas si il inlines
Math.Abs
ou pas... mais avez-vous vérifié que c'est en fait un problème de performance pour vous? N'avez pas de micro-optimiser jusqu'à ce que vous savez que vous en avez besoin, et ensuite mesurer le gain de performance à partir de quelque chose comme:pour vérifier qu'il vaut vraiment le coup.
Comme indiqué par Anthony, le ci-dessus ne sont pas (normalement) travaillent pour
int.MinValue
comme-int.MinValue == int.MinValue
alors queMath.Abs
va jeter unOverflowException
. Vous pouvez forcer cette dans la ligne droite C# ainsi vérifié à l'aide de l'arithmétique:J'ai fait quelques tests de performance, pour savoir si vous pouvez réellement gagner du temps à l'aide de quelque chose en dehors de la norme de Mathématiques.Abs.
Les résultats après l'exécution de l'ensemble de ces 2000000000 fois (avec
i
de -1000000000 à +1000000000, sans débordements):(Ces chiffres varient un peu pour les différentes pistes)
Fondamentalement, vous pouvez obtenir une très légère amélioration par rapport à
Math.Abs
mais rien de spectaculaire.Avec le bit hack vous permet de vous raser un peu de temps requis pour les Mathématiques.Abs, mais la lisibilité souffre gravement.
Avec la simple direction générale, vous pouvez effectivement être plus lent. Globalement ce n'est pas la peine à mon avis.
Tous les tests où s'exécuter sur un OS 32 bits, Net 4.0, visual studio 2010, mode de Libération, pas de débogueur.
Voici le code:
Pour ce que ça vaut, la valeur absolue de 32 bits signé, complément de 2 format int est généralement mis en œuvre comme ceci:
abs(x) = (x^(x>>31))-(x>>31)
Je viens de voir si elle est inférieure à zéro et de le multiplier par -1
Voir http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs pour savoir comment calculer la valeur absolue sans ramification.
Tandis que .Net prend en charge l'in-lining, je doute que
Math.Abs()
serait considéré comme un candidat pour un alignement par le compilateur. Voici la mise en œuvre de laint
surcharge, avec l'aimable autorisation de Réflecteur.Les surcharges pour les autres types intégraux sont similaires. Le
float
etdouble
surcharges sont les appels externes, tandis que ladecimal
surcharge utilise sa propre mise en œuvre, qui construit une nouvelle instance. Ouch!C# ne inline Mathématiques.Abs. Cela fonctionne: