Differenza di prestazioni tra IIf () e If


Risposte:


140

VB ha la seguente Ifdichiarazione a cui si riferisce la domanda, penso:

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

Il primo è fondamentalmente l'operatore condizionale ternario di C # e il secondo è il suo operatore di coalesce (return a resultmeno che non lo sia Nothing, nel qual caso return "Alternative"). Ifè così sostituito IIfe quest'ultimo è obsoleto.

Come in C #, l' Ifoperatore condizionale di VB va in cortocircuito, quindi ora puoi scrivere in sicurezza quanto segue, cosa non possibile utilizzando la IIffunzione:

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

2
Non hai risposto alla domanda sulle prestazioni e non hai nemmeno menzionato gli effetti collaterali di IIf.
jor

2
@jor L'ultimo paragrafo della mia risposta riguarda gli effetti collaterali. Le prestazioni non sono realmente rilevanti quando una delle opzioni è obsoleta. Per quel che vale, l'operatore nativo Ifè IIfdi gran lunga più efficiente della funzione.
Konrad Rudolph

2
@mmcrae È corretto e apposta: come ho detto, IIf è obsoleto, quindi non ha molto senso discuterne. Detto questo, il mio ultimo paragrafo discute la differenza rilevante. Questo è tutto ciò che devi sapere, davvero.
Konrad Rudolph

2
Apprezzo che tu voglia supportare buoni standard e assicurarti che i neofiti non prendano cattive pratiche, ma qualcuno potrebbe avere un problema perfettamente legittimo che gli ha fatto desiderare di capire meglio la differenza ... come mantenere il codice legacy, essere bloccato con qualche altro strumento che lo utilizza, ecc. E That's all you need to know, reallynon sembra un atteggiamento favorevole per un sito web dedicato alla condivisione della conoscenza;)
Don Cheadle

1
@mmcrae Oh, non volevo essere sprezzante, volevo solo dire che gli interni di IIf sono noiosamente banali. Contiene semplicemente un'istruzione If convenzionale, il che implica che l'ultimo pezzo di codice nella mia risposta non verrebbe eseguito.
Konrad Rudolph

65

IIf()esegue sia il codice vero che quello falso. Per cose semplici come l'assegnazione numerica, questo non è un grosso problema. Ma per il codice che richiede qualsiasi tipo di elaborazione, stai sprecando cicli che eseguono la condizione che non corrisponde e che potrebbero causare effetti collaterali.

Illustrazione del codice:

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

Uscite:

Foo!
Bar!

13

Inoltre, un altro grosso problema con IIf è che in realtà chiamerà tutte le funzioni che sono negli argomenti [1], quindi se hai una situazione come la seguente:

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

In realtà genererà un'eccezione, che non è il modo in cui la maggior parte delle persone pensa che la funzione funzioni la prima volta che la vedono. Questo può anche portare ad alcuni bug molto difficili da correggere in un'applicazione.

[1] Funzione IIf - http://msdn.microsoft.com/en-us/library/27ydhh0d(VS.71).aspx


Questo è il motivo per cui se venivo a sostituire il vecchio IIF, avevo problemi con IIF ma IF salvavo aggiungendo molte righe di codice.
NiL

7

Meglio usare If invece di IIf per usare correttamente il meccanismo di inferenza del tipo (Option Infer On)

In questo esempio, le parole chiave vengono riconosciute come una stringa quando utilizzo If:

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

Altrimenti, viene riconosciuto come Oggetto:

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

6

Secondo questo ragazzo , IIf può richiedere fino a 6 volte il tempo di If / Then. YMMV.


1
Nei miei calcoli empirici (10000000 cicli), ho valutato che IIf fosse circa 12 volte più lento!
Phantômaxx

6

Inoltre, in questo caso, la leggibilità dovrebbe essere probabilmente maggiormente preferita rispetto alle prestazioni. Anche se IIF fosse più efficiente, è semplicemente meno leggibile per il pubblico di destinazione (presumo che se stai lavorando in Visual Basic, vuoi che altri programmatori siano in grado di leggere facilmente il tuo codice, che è il più grande vantaggio di VB ... e che si perde con concetti come IIF secondo me).

Inoltre, "IIF è una funzione, contro IF fa parte della sintassi dei linguaggi" ... il che implica per me che, in effetti, If sarebbe più veloce ... se non altro l'istruzione If può essere ridotta direttamente a un piccolo insieme di codici operativi piuttosto che dover andare in un altro spazio della memoria per eseguire la logica trovata in detta funzione. È una differenza banale, forse, ma vale la pena notare.


6

Credo che la principale differenza tra If e IIf sia:

  • If (test [boolean], statement1, statement2) significa che in base al valore del test verranno eseguiti satement1 o statement2 (verrà eseguita solo un'istruzione)

  • Dim obj = IIF (test [boolean], statement1, statement2) significa che entrambe le istruzioni verranno eseguite ma in base al valore di test una di esse restituirà un valore a (obj).

quindi, se una delle istruzioni genera un'eccezione, la lancia comunque in (IIf) ma in (If) la lancia nel caso in cui la condizione restituisca il suo valore.


5

... sul motivo per cui può richiedere fino a 6x, afferma il wiki:

Poiché IIf è una funzione di libreria, richiederà sempre l'overhead di una chiamata di funzione, mentre un operatore condizionale produrrà molto probabilmente codice inline.

Essenzialmente IIf è l'equivalente di un operatore ternario in C ++ / C #, quindi ti dà alcune belle istruzioni di tipo if / else di 1 riga se lo desideri. Puoi anche dargli una funzione da valutare se lo desideri.


1

Queste funzioni sono diverse! Forse hai solo bisogno di usare l'istruzione IF. IIF sarà sempre più lento, perché eseguirà entrambe le funzioni più l'istruzione IF standard.

Se ti stai chiedendo perché esiste la funzione IIF, forse questa sarà una spiegazione:

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

Quindi il contatore sarà 2 dopo questo, ma solo "SÌ". So che questa roba del contatore è inutile, ma a volte ci sono funzioni che dovrai eseguire entrambe, non importa se IF è vero o falso, e assegna semplicemente il valore da uno di loro alla tua variabile.


se hai bisogno di entrambi per eseguire, dovresti chiamarli esplicitamente entrambi e quindi eseguire uno standard If. Usarlo IIf()in questo modo confonderà le persone che leggono il tuo codice.
Spivonious

Lo so, ma la domanda riguarda la differenza tra questi due.
titol

Non volevo che il commento si presentasse come una critica; Stavo solo facendo notare che usarlo in questo modo non è una buona pratica.
Spivonious
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.