在Visual Basic中,使用IIf函数而不是If语句时,性能会有差异吗?
我认为,VB有以下问题引用的If语句:
1 2 3 4
| ' Usage 1
Dim result = If(a > 5,"World","Hello")
' Usage 2
Dim foo = If(result,"Alternative") |
第一个基本上是C#的三元条件运算符,第二个是其合并运算符(除非为Nothing,否则返回result,在这种情况下,返回"Alternative")。 If因此已替换IIf,而后者已过时。
像在C#中一样,VB的条件If运算符发生短路,因此您现在可以安全地编写以下内容,而使用IIf函数是不可能的:
1
| Dim len = If(text Is Nothing, 0, text.Length) |
IIf()同时运行正确和错误代码。对于简单的事情,例如数字赋值,这没什么大不了的。但是对于需要任何类型处理的代码,您浪费的是运行条件不匹配的循环,并可能导致副作用。
代码说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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 |
输出:
另外,IIf的另一个大问题是它实际上会调用参数[1]中的任何函数,因此,如果您遇到以下情况:
1
| string results = IIf(Not oraData.IsDBNull(ndx), oraData.GetString(ndx), string.Empty) |
实际上,它将引发异常,这不是大多数人第一次看到该功能时认为的功能。这也可能导致一些很难修复的应用程序中的错误。
[1] IIf函数-http://msdn.microsoft.com/zh-cn/library/27ydhh0d(VS.71).aspx
更好地使用If而不是IIf来正确使用类型推断机制(Option Infer On)
在此示例中,当我使用If时,关键字被识别为字符串:
1
| Dim Keywords = If(String.IsNullOrEmpty(SelectedKeywords),"N/A", SelectedKeywords) |
否则,将其识别为Object:
1
| Dim Keywords = IIf(String.IsNullOrEmpty(SelectedKeywords),"N/A", SelectedKeywords) |
我相信If和IIf之间的主要区别是:
因此,如果其中一条语句将引发异常,则无论如何它都会将其引发到(IIf)中,但在(If)中它将引发该异常,以防万一条件将返回其值。
最重要的是,在这种情况下,可读性可能比性能更受青睐。即使IIF效率更高,目标读者也很难理解(我假设如果您使用的是Visual Basic,您希望其他程序员能够轻松地阅读您的代码,这是VB的最大福音。在我看来,这些东西已经被诸如IIF之类的概念所迷失了。
另外," IIF是一个函数,而IF是语言语法的一部分"……对我而言,这确实意味着,If会更快……If除此之外,If语句可以直接分解为而不是去存储器中的另一个空间来执行所述功能中找到的逻辑,而不是访问一小部分操作码。也许这是一个古朴的区别,但值得注意。
根据这个家伙的说法,IIf最多可以使用If / Then的6倍。 YMMV。
...关于为什么可能需要长达6倍的时间,请引用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.
IIf本质上等效于C ++ / C#中的三元运算符,因此如果您愿意,它可以为您提供一些不错的1行if / else类型语句。您还可以给它一个评估您是否需要的功能。
这些功能是不同的!也许您只需要使用IF语句。
IIF总是会变慢,因为它将同时执行两个功能以及执行标准的IF语句。
如果您想知道为什么有IIF函数,也许可以这样解释:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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 |
因此,此后计数器将为2,但s仅为" YES"。我知道这个计数器的东西是没有用的,但是有时有些函数需要您都运行,如果IF是true还是false都没关系,只需将其中一个的值赋给变量即可。