Leistungsunterschied zwischen IIf () und If

98

Gibt es in Visual Basic einen Leistungsunterschied, wenn die IIfFunktion anstelle der IfAnweisung verwendet wird?

Bryan Roth
quelle

Antworten:

140

VB hat die folgende IfAussage, auf die sich die Frage bezieht, denke ich:

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

Der erste ist im Grunde der ternäre bedingte Operator von C # und der zweite ist der Koaleszenzoperator (return, es resultsei denn, dies ist Nothingder Fall "Alternative"). Ifhat somit ersetzt IIfund letzteres ist veraltet.

Wie in C # schließt der bedingte IfOperator von VB kurz, sodass Sie jetzt sicher Folgendes schreiben können, was mit der IIfFunktion nicht möglich ist:

Dim len = If(text Is Nothing, 0, text.Length)
Konrad Rudolph
quelle
2
Sie haben die Leistungsfrage nicht beantwortet und auch die Nebenwirkungen von nicht erwähnt IIf.
jor
2
@jor Der letzte Absatz meiner Antwort handelt von den Nebenwirkungen. Die Leistung ist nicht wirklich relevant, wenn eine der Optionen veraltet ist. Für das, was es wert ist, ist der native Operator bei weitem Ifeffizienter als die IIfFunktion.
Konrad Rudolph
2
@mmcrae Das ist richtig und absichtlich: Wie ich bereits sagte, ist IIf veraltet, daher macht es wenig Sinn, darüber zu diskutieren. In meinem letzten Absatz wird jedoch der relevante Unterschied erörtert. Das ist wirklich alles, was Sie wissen müssen.
Konrad Rudolph
2
Ich weiß es zu schätzen, dass Sie gute Standards unterstützen und sicherstellen möchten, dass Neulinge keine schlechten Praktiken aufgreifen, aber jemand hat möglicherweise ein absolut legitimes Problem, das dazu geführt hat, dass er den Unterschied besser verstehen möchte ein anderes Tool, das es verwendet, etc. Und That's all you need to know, reallyklingt nicht nach einer förderlichen Einstellung für eine Website, die sich dem Wissensaustausch widmet;)
Don Cheadle
1
@mmcrae Oh, ich wollte nicht abweisend sein, ich wollte nur wirklich, dass die Interna von IIf langweilig trivial sind. Es enthält einfach eine herkömmliche If-Anweisung, die impliziert, dass der letzte Code in meiner Antwort nicht ausgeführt wird.
Konrad Rudolph
65

IIf()führt sowohl den wahren als auch den falschen Code aus. Für einfache Dinge wie die numerische Zuweisung ist dies keine große Sache. Bei Code, der eine Verarbeitung erfordert, verschwenden Sie jedoch Zyklen, in denen die nicht übereinstimmende Bedingung ausgeführt wird, und verursachen möglicherweise Nebenwirkungen.

Code-Abbildung:

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

Ausgänge:

Foo!
Bar!
Thomas G. Mayfield
quelle
13

Ein weiteres großes Problem mit dem IIf ist, dass es tatsächlich alle Funktionen aufruft, die in den Argumenten [1] enthalten sind. Wenn Sie also eine Situation wie die folgende haben:

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

Es wird tatsächlich eine Ausnahme auslösen, so wie die meisten Leute nicht denken, dass die Funktion funktioniert, wenn sie sie zum ersten Mal sehen. Dies kann auch zu sehr schwer zu behebenden Fehlern in einer Anwendung führen.

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

rjzii
quelle
Aus diesem Grund hatte ich früher Probleme mit IIF, als ich das alte IIF ersetzte, aber IF sparte das Hinzufügen vieler Codezeilen.
NiL
7

Besser verwenden If anstelle von IIf, um den Typinferenzmechanismus korrekt zu verwenden (Option Infer On)

In diesem Beispiel werden Schlüsselwörter als Zeichenfolge erkannt, wenn ich If:

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

Andernfalls wird es als Objekt erkannt:

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

Laut diesem Typen kann IIf bis zu 6x so lange dauern wie If / Then. YMMV.

Greg Hurlman
quelle
1
In meinen empyrischen Berechnungen (10000000 Zyklen) habe ich IIf als ungefähr 12x langsamer bewertet!
Phantômaxx
6

Darüber hinaus sollte in diesem Fall die Lesbarkeit wahrscheinlich stärker bevorzugt werden als die Leistung. Selbst wenn IIF effizienter war, ist es für die Zielgruppe einfach weniger lesbar (ich nehme an, wenn Sie in Visual Basic arbeiten, möchten Sie, dass andere Programmierer Ihren Code leicht lesen können, was der größte Segen von VB ist ... und was meiner Meinung nach mit Konzepten wie IIF verloren geht).

Außerdem ist "IIF eine Funktion, wenn IF Teil der Sprachsyntax ist" ... was für mich impliziert, dass If in der Tat schneller wäre ... wenn für nichts anderes als das die If-Anweisung direkt heruntergekocht werden kann zu einem kleinen Satz von Opcodes, anstatt zu einem anderen Speicherplatz gehen zu müssen, um die in dieser Funktion gefundene Logik auszuführen. Es ist vielleicht ein kleiner Unterschied, aber erwähnenswert.

EdgarVerona
quelle
6

Ich glaube, dass der Hauptunterschied zwischen If und IIf ist:

  • Wenn (test [boolean], Anweisung1, Anweisung2) bedeutet dies, dass gemäß dem Testwert entweder satement1 oder Anweisung2 ausgeführt wird (nur eine Anweisung wird ausgeführt).

  • Dim obj = IIF (test [boolean], Anweisung1, Anweisung2) bedeutet, dass beide Anweisungen ausgeführt werden, aber gemäß dem Testwert eine von ihnen einen Wert an (obj) zurückgibt.

Wenn also eine der Anweisungen eine Ausnahme auslöst, wird sie trotzdem in (IIf) ausgelöst, aber in (If) wird sie ausgelöst, nur für den Fall, dass die Bedingung ihren Wert zurückgibt.

irgendein Typ
quelle
5

... warum es bis zu 6x dauern kann, sagt das Wiki:

Da es sich bei IIf um eine Bibliotheksfunktion handelt, ist immer der Overhead eines Funktionsaufrufs erforderlich, während ein bedingter Operator mit größerer Wahrscheinlichkeit Inline-Code erzeugt.

Im Wesentlichen entspricht IIf einem ternären Operator in C ++ / C #, sodass Sie einige nette 1-zeilige if / else-Typanweisungen erhalten, wenn Sie dies möchten. Sie können ihm auch eine Funktion geben, um zu bewerten, ob Sie dies wünschen.

Dillie-O
quelle
1

Diese Funktionen sind unterschiedlich! Möglicherweise müssen Sie nur die IF-Anweisung verwenden. IIF ist immer langsamer, da es beide Funktionen und die Standard-IF-Anweisung ausführt.

Wenn Sie sich fragen, warum es eine IIF-Funktion gibt, ist dies möglicherweise eine Erklärung:

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

Danach ist der Zähler 2, aber s ist nur "JA". Ich weiß, dass dieses Zählermaterial nutzlos ist, aber manchmal gibt es Funktionen, die Sie beide ausführen müssen, egal ob IF wahr oder falsch ist, und weisen Sie Ihrer Variablen einfach einen Wert von einer davon zu.

Titol
quelle
Wenn Sie beide zum Ausführen benötigen, sollten Sie beide explizit aufrufen und dann ein Standard-If ausführen. Die Verwendung IIf()auf diese Weise wird nur die Leute verwirren, die Ihren Code lesen.
Spivonious
Ich weiß das, aber bei der Frage geht es um den Unterschied zwischen diesen beiden.
Titol
Ich wollte nicht, dass der Kommentar als Kritik rüberkommt. Ich habe nur darauf hingewiesen, dass es keine gute Praxis ist, es auf diese Weise zu verwenden.
Spivonious