Differenza di prestazioni tra IIf () e If

In Visual Basic, c’è una differenza di prestazioni quando si utilizza la funzione IIf anziché l’istruzione If ?

VB ha la seguente istruzione If cui la domanda si riferisce, penso:

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

Il primo è in pratica l’operatore condizionale ternario di C # e il secondo è il suo operatore di coalizione (restituisce il result meno che non sia Nothing , nel qual caso restituisce "Alternative" ). If ha quindi sostituito IIf e quest’ultimo è obsoleto.

Come in C #, l’operatore condizionale di VB If cortocircuiti, così ora puoi scrivere in modo sicuro quanto segue, cosa che non è ansible usando la funzione IIf :

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

IIf() esegue sia il codice vero che 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 con condizioni che non corrispondono e che potrebbero causare effetti collaterali.

Illustrazione 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! 

Inoltre, un altro grosso problema con l’IIf è che in realtà chiamerà qualsiasi funzione presente negli argomenti [1], quindi se hai una situazione simile alla seguente:

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

In realtà genererà un’eccezione, il 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

Migliore utilizzo Se al posto di IIf utilizzare correttamente il meccanismo di inferenza del tipo (Opzione Infer In)

In questo esempio, le parole chiave sono riconosciute come una stringa quando uso If:

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

Altrimenti, è riconosciuto come object:

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

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

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

Inoltre, “IIF è una funzione, contro l’IF che fa parte della syntax dei linguaggi” … il che implica che, in realtà, se sarebbe più veloce … se non altro per il fatto che l’istruzione If può essere ridotta direttamente a un piccolo insieme di opcode anziché dover andare in un altro spazio in memoria per eseguire la logica trovata in detta funzione. È una differenza banale, forse, ma vale la pena notare.

Credo che la differenza principale tra If e IIf sia:

  • Se (test [booleano], istruzione1, istruzione2) significa che, in base al valore del test, verranno eseguiti sia Satement1 sia Statement2 (verrà eseguita solo una istruzione)

  • Dim obj = IIF (test [booleano], istruzione1, istruzione2) significa che entrambe le istruzioni verranno eseguite, ma in base al valore di test uno di essi restituirà un valore a (obj).

quindi se una delle affermazioni lancia un’eccezione, la butta comunque in (IIf) ma in (If) la getterà nel caso in cui la condizione restituisca il suo valore.

… sul motivo per cui può richiedere fino a 6x, quoth il wiki:

Poiché IIf è una funzione di libreria, richiederà sempre il sovraccarico di una chiamata di funzione, mentre un operatore condizionale produrrà più probabilmente codice inline.

Essenzialmente IIf è l’equivalente di un operatore ternario in C ++ / C #, quindi ti dà delle belle frasi di tipo 1 line if / else se ti piacerebbe. Puoi anche dargli una funzione per valutare se lo desideri.

Quelle funzioni sono diverse! Forse hai solo bisogno di usare la dichiarazione di IF. IIF sarà sempre più lento, perché farà entrambe le funzioni più farà un’istruzione IF standard.

Se ti stai chiedendo perché esiste la funzione IIF, forse questa sarà la 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 s sarà solo “SÌ”. So che questo contatore è inutile, ma a volte ci sono funzioni che è necessario eseguire entrambe, non importa se IF è vero o falso, e basta assegnare un valore da una di esse alla variabile.