2009-09-16 7 views
2

Ce qui est généralement plus rapide:Comparaison efficacité

if (num >= 10) 

ou:

if (!(num < 10)) 
+6

num> = 10, si seulement pour la lisibilité ... –

+1

dans quelle langue? –

Répondre

25

Le compilateur optimisera très probablement ce genre de chose. Ne vous inquiétez pas à ce sujet, il suffit de coder pour plus de clarté dans ce cas.

langues de l'Assemblée ont souvent des opérations pour >= et <= qui sont le même nombre d'étapes que < et >. Par exemple, avec un Motorola 68k, si vous voulez comparer les registres de données %d0 et %d1 et la branche si %d0 est supérieur ou égal à %d1, vous dire quelque chose comme:

cmp %d0, %d1 // compare %d0 and %d1, storing the result 
       // in the condition code registers. 
bge labelname // Branch to the given label name if the comparison 
       // yielded "greater than or equal to" (hence bge) 

Il est une erreur commune de penser que a >= b signifie que l'ordinateur effectuera deux opérations au lieu d'une à cause de ce "ou" dans "supérieur ou égal à".

+0

Si l'optimiseur ne l'optimise pas, obtenez un meilleur compilateur! –

11

Tout compilateur décent permettra d'optimiser ces deux déclarations exactement le même code sous-jacent. En fait, il sera très générer probablement exactement le même code pour:

if (!(!(!(!(!(!(!(num < 10)))))))) 

Je choisirais pour la première de la vôtre juste parce que son intention semble beaucoup plus claire (légèrement plus claire que votre deuxième choix, massivement plus claire que celle monstruosité j'ai posté ci-dessus). J'ai tendance à penser en termes de comment je le lirais. Pensez aux deux phrases:

  • si le nombre est supérieur ou égal à dix.
  • si ce n'est pas le cas, ce nombre est inférieur à dix.

Je crois que le premier à être plus clair.

En fait, les tests juste avec "gcc -s" pour obtenir la sortie de l'assembleur, les deux déclarations générer le code suivant:

cmpl $9,-8(%ebp) ; compare value with 9 
jle .L3   ; branch if 9 or less. 

Je crois que vous perdez votre temps à regarder des micro-Optimisations comme celui-ci - vous feriez être beaucoup plus efficace en regardant des choses comme la sélection d'algorithmes. Il y aura probablement un retour sur investissement beaucoup plus important.

3

En général, toute différence de vitesse importe peu, mais ne signifie pas nécessairement exactement la même chose.

Dans de nombreux langages, la comparaison de la valeur à virgule flottante NaN renvoie false pour toutes les comparaisons, donc si num = NaN, le premier est faux et le second vrai.

#include <iostream> 
#include <limits> 

int main () { 
    using namespace std; 

    double num = numeric_limits<double>::quiet_NaN(); 

    cout << boolalpha; 
    cout << "(num >= 10)  " << (num >= 10) << endl; 
    cout << "(! (num < 10)) " << (! (num < 10)) << endl; 

    cout << endl; 
} 

sorties

(num >= 10)  false 
(! (num < 10)) true 

Ainsi, le compilateur peut utiliser une seule instruction pour comparer num et la valeur 10 dans le premier cas, mais dans le second peut émettre une seconde instruction pour inverser le résultat de la Comparaison.(ou il peut simplement utiliser une branche si zéro plutôt que la branche si non nulle, vous ne pouvez pas dire en général)

D'autres langages et compilateurs peuvent varier, et pour les types où ils ont vraiment la même sémantique, le code émis pourrait bien être identique.