In Visual Basic, is there a performance difference when using the IIf function instead of the If statement?
According to this guy, IIf can take up to 6x as long as If/Then. YMMV.
...as to why it can take as long as 6x, quoth the wiki:
Because IIf is a library function, it will always require the overhead of a function call, whereas a conditional operator will more likely produce inline code.
Essentially IIf is the equivalent of a ternary operator in C++/C#, so it gives you some nice 1 line if/else type statements if you'd like it to. You can also give it a function to evaluate if you desire.
IIF is an inline-if statement.
Dim x as Integer
If [condition] Then
x = 1
Else
x = 2
End If
vs
Dim x as Integer = IIF( [condition], 1, 2)
In VB this is mimic-ing an language feature that it doesn't have. The IIF implies a type conversion or a remote call that the If-block doesn't.
On top of that, readability should probably be more highly preferred than performance in this case. Even if IIF was more efficient, it's just plain less readable to the target audience (I assume if you're working in Visual Basic, you want other programmers to be able to read your code easily, which is VB's biggest boon... and which is lost with concepts like IIF in my opinion).
Also, "IIF is a function, versus IF being part of the languages' syntax"... which implies to me that, indeed, If would be faster... if for nothing else than that the If statement can be boiled down directly to a small set of opcodes rather than having to go to another space in memory to perform the logic found in said function. It's a trite difference, perhaps, but worth noting.
IIf() runs both the true and false code. For simple things like numeric assignment, this isn't a big deal. But for code that requires any sort of processing, you're wasting cycles running the condition that doesn't match, and possibly causing side effects.
@Dillio-O: Ternary expressions in C# do not execute both expressions.
EDIT: Code illustration:
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
Outputs:
Foo!
Bar!
Also, another big issue with the IIf is that it will actually call any functions that are in the arguments [1], so if you have a situation like the following:
string results = IIf(Not oraData.IsDBNull(ndx), oraData.GetString(ndx), string.Empty)
It will actually throw an exception, which is not how most people think the function works the first time that they see it. This can also lead to some very hard to fix bugs in an application as well.
[1] IIf Function - http://msdn.microsoft.com/en-us/library/27ydhh0d(VS.71).aspx
VB has the following If
statement which the question referred to, I think:
' Usage 1
Dim result = If(a > 5, "World", "Hello")
' Usage 2
Dim foo = If(result Is Nothing, "Alternative")
The first is basically C#'s ternary conditional operator and the second is its coalesce operator. If
has thus replaced IIf
and the latter is obsolete.
/EDIT: Like in C#, VB's conditional If
operator is short-circuit so you can now safely write the following, which is not possible using the IIf
function:
Dim len = If(text Is Nothing, 0, text.Length)
@Konrad: Interesting, I never knew VB had that kind of If statement.
Better use If instead of IIf to use the type inference mechanism correctly (Option Infer On)
In this example, Keywords is recognized as a string when I use If :
Dim Keywords = If(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)
Otherwise, it is recognized as an Object :
Dim Keywords = IIf(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)
I believe that the main difference between If and IIf is:
If(test [boolean], statement1, statement2) it means that according to the test value either satement1 or statement2 will executed (just one statement will execute)
Dim obj = IIF(test [boolean] , statement1, statement2) it means that the both statements will execute but according to test value one of them will return a value to (obj).
so if one of the statements will throw an exception it will throw it in (IIf) anyway but in (If) it will throw it just in case the condition will return its value.