Diferença de desempenho entre IIf () e If

98

No Visual Basic, há uma diferença de desempenho ao usar a IIffunção em vez da Ifinstrução?

Bryan Roth
fonte

Respostas:

140

VB tem a seguinte Ifdeclaração a que a pergunta se refere, eu acho:

' 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 de coalescência (retornar a resultmenos que seja Nothing, nesse caso retornar "Alternative"). Iffoi assim substituído IIfe o último está obsoleto.

Como em C #, o Ifoperador condicional do VB entra em curto-circuito, então agora você pode escrever com segurança o seguinte, o que não é possível usando a IIffunção:

Dim len = If(text Is Nothing, 0, text.Length)
Konrad Rudolph
fonte
2
Você não respondeu à pergunta sobre desempenho e também não mencionou os efeitos colaterais de IIf.
jor
2
@jor O último parágrafo da minha resposta é sobre os efeitos colaterais. O desempenho não é realmente relevante quando uma das opções está obsoleta. Pelo que vale a pena, o operador nativo Ifé muito mais eficiente do que a IIffunção.
Konrad Rudolph
2
@mmcrae Correto e propositalmente: como eu disse, IIf é obsoleto, então não faz sentido discutir isso. Dito isso, meu último parágrafo discute a diferença relevante. Isso é tudo que você precisa saber, realmente.
Konrad Rudolph
2
Agradeço que você queira oferecer suporte a bons padrões e garantir que os novatos não adotem práticas ruins, mas alguém pode ter um problema perfeitamente legítimo que os fez querer entender melhor a diferença ... Como manter o código legado, ficar preso a alguma outra ferramenta que o use, etc. E That's all you need to know, reallynão parece uma atitude favorável para um site dedicado ao compartilhamento de conhecimento;)
Don Cheadle
1
@mmcrae Oh, eu não quis ser desdenhoso, eu apenas quis dizer que as partes internas do IIf são tediosamente triviais. Ele simplesmente contém uma instrução If convencional, o que implica que a última parte do código em minha resposta não funcionaria.
Konrad Rudolph
65

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 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!
Thomas G. Mayfield
fonte
13

Além disso, outro grande problema com o IIf é que ele realmente chamará quaisquer funções que estejam 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, ele 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

rjzii
fonte
É por isso que se viesse a substituir o antigo IIF, eu costumava ter problemas com o IIF, mas eu economizava adicionando muitas linhas de código.
NiL
7

É melhor usar If em vez de IIf para usar o mecanismo de inferência de tipo corretamente (Opção Infer On)

Neste exemplo, palavras-chave são reconhecidas como uma string quando eu uso If:

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

Caso contrário, é reconhecido como um objeto:

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

De acordo com esse cara , IIf pode levar até 6x mais do que If / Then. YMMV.

Greg Hurlman
fonte
1
Em meus cálculos empíricos (10000000 ciclos), avaliei IIf sendo cerca de 12 vezes mais lento!
Phantômaxx 01 de
6

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

Além disso, "IIF é uma função, versus IF sendo parte da sintaxe das linguagens" ... o que implica para mim que, de fato, If seria mais rápido ... se por nada mais do que a instrução If pode ser reduzida diretamente para um pequeno conjunto de opcodes ao invés de ter que ir para outro espaço na memória para realizar a lógica encontrada na referida função. É uma diferença banal, talvez, mas vale a pena notar.

EdgarVerona
fonte
6

Acredito que a principal diferença entre If e IIf é:

  • Se (teste [boolean], instrução1, instrução2), significa que de acordo com o valor de teste ou satement1 ou instrução2 será executado (apenas uma instrução será executada)

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

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

algum cara
fonte
5

... por que pode demorar até 6x, quoth o wiki:

Como IIf é uma função de 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 você quiser. Você também pode atribuir a ele uma função para avaliar, se desejar.

Dillie-O
fonte
1

Essas funções são diferentes! Talvez você só precise usar a instrução IF. IIF será sempre mais lento, porque fará as duas 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 essa coisa de contador é inútil, mas às vezes há funções que você precisará de ambas para executar, não importa se IF é verdadeiro ou falso, e apenas atribua o valor de uma delas à sua variável.

titol
fonte
se você precisar que ambos sejam executados, chame-os explicitamente e faça um If padrão. Usar IIf()dessa forma só vai confundir as pessoas que estão lendo seu código.
Spivonious
Eu sei disso, mas a questão é sobre a diferença entre os dois.
titol
Eu não queria que o comentário parecesse uma crítica; Eu estava apenas apontando que usá-lo dessa forma não é uma boa prática.
Spivonious