IIf()和If之间的性能差异


Answers:


140

If我认为,VB有以下提到该问题的陈述:

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

第一个基本上是C#的三元条件运算符,第二个是其合并运算符(result除非为Nothing,否则返回"Alternative")。If因此已被替换IIf,后者已过时。

像在C#中一样,VB的条件If运算符发生短路,因此您现在可以安全地编写以下内容,这是使用该IIf函数无法实现的:

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

2
您没有回答性能问题,也没有提到的副作用IIf
约旦

2
@jor我的答案的最后一段是关于副作用的。如果其中一个选项已过时,则性能并不重要。就其价值而言,到目前为止,本机运算符If比该IIf函数更有效。
康拉德·鲁道夫

2
@mmcrae是正确的,是故意的:正如我所说的,IIf已经过时了,因此讨论它毫无意义。就是说,我的最后一段确实讨论了相关的区别。真的,这就是您所需要知道的。
康拉德·鲁道夫

2
非常感谢您希望支持良好的标准并确保新手不会采取不良做法,但是有人可能会遇到一个完全合法的问题,这使他们希望更好地了解它们之间的区别……例如维护遗留代码,以及使用它的其他一些工具,等等。That's all you need to know, really对于专门用于知识共享的网站,这听起来似乎不太有利;)
Don Cheadle 2015年

1
@mmcrae哦,我并不是故意要不屑一顾,我只是说IIf的内部结构非常琐碎。它仅包含常规的If语句,这意味着答案中的最后一段代码将无法运行。
Konrad Rudolph

65

IIf()运行正确和错误的代码。对于简单的事情,例如数字赋值,这没什么大不了的。但是对于需要任何类型处理的代码,您浪费的是循环运行条件不匹配的条件,并可能导致副作用。

代码说明:

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

输出:

Foo!
Bar!

13

另外,IIf的另一个大问题是它实际上会调用参数[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


这就是为什么如果要替换旧的IIF,我曾经遇到过IIF问题,但是IF保存了很多行代码。
NiL 2014年

7

更好地使用If代替IIf来正确使用类型推断机制(Option Infer On)

在此示例中,当我使用If时,关键字被识别为字符串:

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

否则,将其识别为Object:

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


6

最重要的是,在这种情况下,可读性可能比性能更受重视。即使IIF效率更高,目标读者也很难理解(我假设如果您使用的是Visual Basic,您希望其他程序员能够轻松地阅读您的代码,这是VB的最大福音。在我看来,这些东西已经被诸如IIF之类的概念所迷失了。

同样,“ IIF是一个函数,而IF是语言语法的一部分” ……对我而言,这确实意味着,If会更快……If除此之外,If语句可以直接分解为到一小部分操作码,而不必去存储器中的另一个空间来执行所述功能中发现的逻辑。也许这是个古朴的区别,但值得注意。


6

我认为If和IIf之间的主要区别是:

  • if(test [boolean],statement1,statement2)表示根据测试值,将执行satement1或statement2(仅执行一条语句)

  • Dim obj = IIF(test [boolean],statement1,statement2),这意味着这两个语句都将执行,但是根据测试值,其中之一将向(obj)返回一个值。

因此,如果其中一条语句将引发异常,则无论如何它将在(IIf)中将其引发,但在(If)中将其将其引发以防万一条件将返回其值。


5

...关于为什么可能需要长达6倍的时间,请引用Wiki:

因为IIf是一个库函数,所以它将始终需要函数调用的开销,而条件运算符则更有可能产生内联代码。

IIf本质上等效于C ++ / C#中的三元运算符,因此如果您愿意,它可以为您提供一些不错的1行if / else类型语句。您还可以给它一个评估您是否需要的功能。


1

这些功能是不同的!也许您只需要使用IF语句。IIF总是会变慢,因为它将同时执行两个功能以及执行标准的IF语句。

如果您想知道为什么有IIF函数,也许可以这样解释:

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都没有关系,只需将其中之一的值赋给变量即可。


如果您需要同时运行它们,则应显式地将它们都调用,然后执行标准的If。IIf()以这种方式使用只会使人们在阅读您的代码时感到困惑。
Spivonious

我知道,但是问题在于这两者之间的区别。
titol '16

我的意思不是说评论是批评。我只是指出,以这种方式使用它不是一个好习惯。
Spivonious
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.