Différence de performances entre IIf () et If


Réponses:


140

VB a la Ifdéclaration suivante à laquelle la question se réfère, je pense:

' Usage 1
Dim result = If(a > 5, "World", "Hello")
' Usage 2
Dim foo = If(result, "Alternative")

Le premier est essentiellement l'opérateur conditionnel ternaire de C # et le second est son opérateur de fusion (return resultsauf si c'est Nothing, auquel cas return "Alternative"). Ifa donc remplacé IIfet ce dernier est obsolète.

Comme dans C #, l' Ifopérateur conditionnel de VB court-circuite, vous pouvez donc maintenant écrire en toute sécurité ce qui suit, ce qui n'est pas possible en utilisant la IIffonction:

Dim len = If(text Is Nothing, 0, text.Length)

2
Vous n'avez pas répondu à la question sur les performances et ne mentionnez pas non plus les effets secondaires de IIf.
jor

2
@jor Le dernier paragraphe de ma réponse concerne les effets secondaires. La performance n'est pas vraiment pertinente lorsque l'une des options est obsolète. Pour ce que ça vaut, l'opérateur natif Ifest IIfde loin plus efficace que la fonction.
Konrad Rudolph

2
@mmcrae C'est correct et exprès: comme je l'ai dit, IIf est obsolète, donc il n'y a pas de sens à en discuter. Cela dit, mon dernier paragraphe traite de la différence pertinente. C'est tout ce que vous devez savoir, vraiment.
Konrad Rudolph

2
J'apprécie que vous souhaitiez soutenir de bonnes normes et vous assurer que les débutants ne prennent pas de mauvaises pratiques, mais quelqu'un peut avoir un problème parfaitement légitime qui les a amenés à vouloir mieux comprendre la différence ... comme maintenir le code hérité, rester coincé avec un autre outil qui l'utilise, etc. Et That's all you need to know, reallycela ne semble pas être une attitude propice pour un site Web consacré au partage des connaissances;)
Don Cheadle

1
@mmcrae Oh, je ne voulais pas être dédaigneux, je voulais juste dire que les éléments internes de IIf sont ennuyeusement triviaux. Il contient simplement une instruction If conventionnelle, ce qui implique que le dernier morceau de code de ma réponse ne s'exécuterait pas.
Konrad Rudolph

65

IIf()exécute à la fois le code vrai et faux. Pour des choses simples comme l'affectation numérique, ce n'est pas un gros problème. Mais pour le code qui nécessite n'importe quel type de traitement, vous perdez des cycles à exécuter la condition qui ne correspond pas et causez peut-être des effets secondaires.

Illustration du code:

Module Module1
    Sub Main()
        Dim test As Boolean = False
        Dim result As String = IIf(test, Foo(), Bar())
    End Sub

    Public Function Foo() As String
        Console.WriteLine("Foo!")
        Return "Foo"
    End Function

    Public Function Bar() As String
        Console.WriteLine("Bar!")
        Return "Bar"
    End Function
End Module

Les sorties:

Foo!
Bar!

13

De plus, un autre gros problème avec IIf est qu'il appellera en fait toutes les fonctions qui sont dans les arguments [1], donc si vous avez une situation comme celle-ci:

string results = IIf(Not oraData.IsDBNull(ndx), oraData.GetString(ndx), string.Empty)

Cela lèvera en fait une exception, ce qui n'est pas la façon dont la plupart des gens pensent que la fonction fonctionne la première fois qu'ils la voient. Cela peut également conduire à des bogues très difficiles à corriger dans une application.

[1] Fonction IIf - http://msdn.microsoft.com/en-us/library/27ydhh0d(VS.71).aspx


C'est pourquoi si je venais à remplacer l'ancien IIF, j'avais l'habitude d'avoir des problèmes avec IIF mais IF sauvé l'ajout de nombreuses lignes de code.
NiL

7

Mieux vaut utiliser If au lieu de IIf pour utiliser correctement le mécanisme d'inférence de type (Option Infer On)

Dans cet exemple, les mots clés sont reconnus comme une chaîne lorsque j'utilise If:

Dim Keywords = If(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)

Sinon, il est reconnu comme un objet:

Dim Keywords = IIf(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)

6

Selon ce type , IIf peut prendre jusqu'à 6 fois plus longtemps que If / Then. YMMV.


1
Dans mes calculs empiriques (10000000 cycles), j'ai évalué que IIf était environ 12 fois plus lent!
Phantômaxx

6

En plus de cela, la lisibilité devrait probablement être plus préférée que les performances dans ce cas. Même si IIF était plus efficace, il est tout simplement moins lisible pour le public cible (je suppose que si vous travaillez dans Visual Basic, vous voulez que d'autres programmeurs puissent lire facilement votre code, ce qui est le plus grand avantage de VB ... et ce qui est perdu avec des concepts comme IIF à mon avis).

Aussi, "IIF est une fonction, contre IF faisant partie de la syntaxe des langages" ... ce qui m'implique qu'en effet, If serait plus rapide ... si rien d'autre que cela, l'instruction If peut être résumée directement à un petit ensemble d'opcodes plutôt que d'avoir à aller dans un autre espace de la mémoire pour exécuter la logique trouvée dans ladite fonction. C'est peut-être une différence banale, mais à noter.


6

Je pense que la principale différence entre If et IIf est:

  • Si (test [booléen], instruction1, instruction2) cela signifie que selon la valeur de test, satement1 ou instruction2 sera exécuté (une seule instruction s'exécutera)

  • Dim obj = IIF (test [boolean], statement1, statement2) cela signifie que les deux instructions s'exécuteront mais selon la valeur de test l'une d'elles renverra une valeur à (obj).

donc si l'une des instructions lèvera une exception, elle la lancera quand même dans (IIf) mais dans (If) elle la lancera juste au cas où la condition renverrait sa valeur.


5

... pour savoir pourquoi cela peut prendre jusqu'à 6x, dit le wiki:

Étant donné que IIf est une fonction de bibliothèque, elle nécessitera toujours la surcharge d'un appel de fonction, alors qu'un opérateur conditionnel produira plus probablement du code en ligne.

Essentiellement IIf est l'équivalent d'un opérateur ternaire en C ++ / C #, donc il vous donne de belles instructions de type if / else sur 1 ligne si vous le souhaitez. Vous pouvez également lui donner une fonction pour évaluer si vous le souhaitez.


1

Ces fonctions sont différentes! Vous n'avez peut-être besoin que de l'instruction IF. IIF sera toujours plus lent, car il effectuera les deux fonctions plus il fera l'instruction IF standard.

Si vous vous demandez pourquoi il existe une fonction IIF, ce sera peut-être une explication:

Sub main()
    counter = 0
    bln = True
    s = iif(bln, f1, f2)
End Sub

Function f1 As String
    counter = counter + 1
    Return "YES"
End Function

Function f2 As String
    counter = counter + 1
    Return "NO"
End Function

Ainsi, le compteur sera 2 après cela, mais s sera "OUI" seulement. Je sais que ce compteur est inutile, mais parfois il y a des fonctions dont vous aurez besoin à la fois pour exécuter, peu importe si IF est vrai ou faux, et attribuez simplement la valeur de l'une d'entre elles à votre variable.


si vous avez besoin des deux pour exécuter, vous devez les appeler explicitement tous les deux, puis faire un If standard. Utiliser IIf()de cette manière ne fera que semer la confusion chez les gens qui lisent votre code.
Spivonious

Je le sais, mais la question porte sur la différence entre les deux.
titol

Je ne voulais pas que le commentaire apparaisse comme une critique; Je faisais juste remarquer que l'utiliser de cette manière n'est pas une bonne pratique.
Spivonious
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.