Diferença de desempenho entre IIf () e se

No Visual Basic, há uma diferença de desempenho ao usar a function IIf vez da instrução If ?

VB tem a seguinte instrução If qual a pergunta se refere, penso:

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

O primeiro é basicamente o operador condicional ternário de C # e o segundo é seu operador coalescedor ( result retorno, a menos que seja Nothing , caso em que retorna "Alternative" ). If assim substituiu IIf e este último é obsoleto.

Como em C #, condicional do VB If operador curto-circuitos, então agora você pode escrever com segurança o seguinte, o que não é possível usando a function IIf :

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

IIf() executa o código verdadeiro e falso. Para coisas simples como atribuição numérica, isso não é grande coisa. Mas para o código que requer qualquer tipo de processamento, você está perdendo ciclos executando a condição que não combina e possivelmente causando efeitos colaterais.

Ilustração de código:

 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 

Saídas:

 Foo! Bar! 

Além disso, outro grande problema com o IIf é que ele realmente chamará quaisquer funções que estão nos argumentos [1], portanto, se você tiver uma situação como a seguinte:

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

Ele realmente lançará uma exceção, que não é como a maioria das pessoas acha que a function funciona na primeira vez que a vê. Isso também pode levar a alguns problemas muito difíceis de corrigir erros em um aplicativo também.

[1] Função IIf – http://msdn.microsoft.com/pt-br/library/27ydhh0d(VS.71).aspx

Melhor uso Se em vez de IIf usar o mecanismo de inferência de tipos corretamente (Option Infer On)

Neste exemplo, Keywords é reconhecido como uma string quando eu uso If:

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

Caso contrário, é reconhecido como um object:

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

De acordo com esse cara , o IIf pode levar até 6x enquanto If / Then. YMMV.

Além disso, a legibilidade provavelmente deve ser mais altamente preferida do que o desempenho neste caso. Mesmo se o IIF fosse mais eficiente, ele seria simplesmente menos legível para o público-alvo (suponho que se você estiver trabalhando no Visual Basic, você quer que outros programadores possam ler seu código facilmente, que é o maior benefício do VB … e que é perdido com conceitos como IIF na minha opinião).

Além disso, “IIF é uma function, contra IF sendo parte da syntax das linguagens” … o que implica para mim que, de fato, se seria mais rápido … se por nada mais do que a declaração If pode ser resumida diretamente para um pequeno conjunto de opcodes em vez de ter que ir para outro espaço na memory para executar a lógica encontrada na referida function. É uma diferença banal, talvez, mas digna de nota.

Eu acredito que a principal diferença entre If e IIf é:

  • Se (test [boolean], statement1, statement2) significa que, de acordo com o valor do teste, satement1 ou statement2 serão executados (apenas uma instrução será executada)

  • Dim obj = IIF (teste [booleano], declaração1, instrução2) significa que ambas as instruções serão executadas, mas de acordo com o valor do teste, uma delas retornará um valor para (obj).

então, se uma das instruções lançar uma exceção, ela será lançada em (IIf) de qualquer maneira, mas em (If), ela será lançada apenas no caso de a condição retornar seu valor.

… quanto ao motivo pelo qual pode levar até 6x, entre no wiki:

Como IIf é uma function de biblioteca, sempre exigirá a sobrecarga de uma chamada de function, enquanto um operador condicional provavelmente produzirá código embutido.

Essencialmente IIf é o equivalente a um operador ternário em C ++ / C #, então ele fornece algumas instruções de tipo if / else de 1 linha se você quiser. Você também pode dar uma function para avaliar se você deseja.

Essas funções são diferentes! Talvez você só precise usar a instrução IF. O IIF será sempre mais lento, porque fará as duas funções e fará a declaração IF padrão.

Se você está se perguntando por que existe a function IIF, talvez esta seja uma explicação:

 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 

Então o contador será 2 depois disso, mas s será “SIM” apenas. Eu sei que esse material de contador é inútil, mas às vezes existem funções que você precisará executar, não importa se IF é verdadeiro ou falso, e apenas atribua valor de um deles à sua variável.