Diferença de desempenho entre IIf() e If
-
09-06-2019 - |
Pergunta
No Visual Basic, há uma diferença de desempenho ao usar o IIf
função em vez do If
declaração?
Solução
VB tem o seguinte If
afirmação a que 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 do C# e o segundo é o seu operador coalesce (retorno result
a menos que seja Nothing
, nesse caso retorne "Alternative"
). If
assim substituiu IIf
e este último está obsoleto.
Como em C#, o condicional do VB If
curto-circuito do operador, então agora você pode escrever com segurança o seguinte, o que não é possível usando o IIf
função:
Dim len = If(text Is Nothing, 0, text.Length)
Outras dicas
IIf()
executa o código verdadeiro e falso.Para coisas simples como atribuição numérica, isso não é grande coisa.Mas para código que requer qualquer tipo de processamento, você está desperdiçando ciclos executando a condição que não corresponde e possivelmente causando efeitos colaterais.
Ilustração do 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á qualquer função que esteja 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)
Na verdade, isso lançará uma exceção, que não é como a maioria das pessoas pensa que a função funciona na primeira vez que a vêem.Isso também pode levar a alguns bugs muito difíceis de corrigir em um aplicativo.
[1] Função IIf - http://msdn.microsoft.com/en-us/library/27ydhh0d(VS.71).aspx
É melhor usar If em vez de IIf para usar o mecanismo de inferência de tipo corretamente (Option Infer On)
Neste exemplo, Keywords é reconhecido como uma string quando 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, IIf pode levar até 6x mais que If/Then.YMMV.
Além disso, a legibilidade provavelmente deveria ser mais preferida do que o desempenho neste caso.Mesmo que o IIF fosse mais eficiente, é simplesmente menos legível para o público-alvo (presumo que se você estiver trabalhando em Visual Basic, deseja que outros programadores possam ler seu código facilmente, o que é o maior benefício do VB...e que se perde com conceitos como IIF na minha opinião).
Também, “IIF é uma função, versus IF faz parte da sintaxe das linguagens”...o que implica para mim que, de fato, seria mais rápido...pelo menos, a instrução If pode ser resumida diretamente em um pequeno conjunto de códigos de operação, em vez de ter que ir para outro espaço na memória para executar a lógica encontrada na referida função.É uma diferença banal, talvez, mas digna de nota.
Acredito que a principal diferença entre If e IIf é:
Se (teste [boolean], declaração1, declaração2) significa que, de acordo com o valor do teste, o Satent1 ou a declaração2 será executada (apenas uma declaração será executada)
Dim obj = IIF (teste [boolean], declaração1, declaração2) Isso significa que as duas instruções serão executadas, mas de acordo com o valor do teste, um deles retornará um valor a (OBJ).
portanto, se uma das instruções lançar uma exceção, ela será lançada em (IIf) de qualquer maneira, mas em (If) será lançada apenas no caso de a condição retornar seu valor.
... por que pode demorar até 6x, cita o wiki:
Como o IIF é uma função da biblioteca, sempre exigirá a sobrecarga de uma chamada de função, enquanto um operador condicional provavelmente produzirá código embutido.
Essencialmente, IIf é o equivalente a um operador ternário em C++/C#, portanto, fornece algumas instruções do tipo if/else de 1 linha, se desejar.Você também pode atribuir uma função para avaliar, se desejar.
Essas funções são diferentes!Talvez você só precise usar a instrução IF.IIF sempre será mais lento, porque executará ambas as funções e fará a instrução IF padrão.
Se você está se perguntando por que existe a função IIF, talvez esta seja a 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
Portanto, o contador será 2 depois disso, mas s será apenas “SIM”.Eu sei que esse contador é inútil, mas às vezes há funções que você precisará que ambas executem, não importa se IF é verdadeiro ou falso, e apenas atribua o valor de uma delas à sua variável.