2017-05-30 2 views
1

Ce qui est plus rapide d'un point de vue de l'exécution de code:manière optimale pour annuler une valeur en virgule flottante en C#

double a = 1.234; 
double minus_a = -a; 

ou:

double a = 1.234; 
double minus_a = a * -1; 

Le second cas EFFECTUER fait multiplication à virgule flottante? Ou le compilateur est-il assez intelligent pour optimiser le second cas à être le même que le premier?

+0

Il n'y a aucune raison de supposer que la première serait jamais plus lente que la seconde, et qu'elle est à la fois plus courte et plus conventionnelle. Pourquoi envisageriez-vous même la seconde? –

+0

Savez-vous que vous pouvez [visualiser l'IL compilé] (https://msdn.microsoft.com/en-us/library/f7dy01k1 (v = vs.110) .aspx) et découvrez par vous-même? –

+0

Négation d'une valeur est beaucoup plus simple et lisible que la multiplication! –

Répondre

4

testé avec le 64bit JIT de .NET 4, d'autres JIT tels que l'ancien 32bit JIT ou la plus récente RyuJIT peut être différent (en fait le 32bit vieux JIT doit faire quelque chose d'autre, car il n'utilise pas SSE)

-x se traduit

vmovsd  xmm1,qword ptr [00000050h] ; there's a -0.0 there, so only the sign bit is set 
vxorpd  xmm0,xmm0,xmm1 ; literally flip the sign 

x * -1 dans

vmulsd  xmm0,xmm0,mmword ptr [00000048h] ; -1.0 

Oui, très littéral. Pour la vitesse, vous pouvez choisir votre modèle de here et comparer, mais vxorpd sera toujours plus rapide que vmulsd.

Aurait-il pu optimiser x * -1 à un XOR? Le comportement de NaN est différent, l'approche XOR renversant le signe du NaN, mais cela n'a pas vraiment d'importance.

+0

Génial. Juste ce que je cherchais: "* -1" invoque la multiplication à virgule flottante! Aucune optimisation ici. – Arvind

+0

J'ai écrit un benchmark simple. Résultats: Temps écoulé de la négation 00: 00: 02.6422642 --- * -1 temps écoulé 00: 00: 03.4353435 -------- La multiplication du flotteur est donc plus lente d'environ 30%. – Arvind