Diferencia de rendimiento entre IIf () y If


En Visual Basic, ¿hay una diferencia de rendimiento cuando se usa la función IIf en lugar de la instrucción If?

Author: emlai, 2008-08-26

9 answers

VB tiene la siguiente If declaración a la que se refiere la pregunta, creo:

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

El primero es básicamente el operador condicional ternario de C#y el segundo es su operador coalescente (return result a menos que sea Nothing, en cuyo caso return "Alternative"). If ha sustituido así a IIf y este último es obsoleto.

Al igual que en C#, los cortocircuitos del operador condicional de VB If, por lo que ahora puede escribir de forma segura lo siguiente, lo cual no es posible usando la función IIf:

Dim len = If(text Is Nothing, 0, text.Length)
 132
Author: Konrad Rudolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-16 16:03:42

IIf() ejecuta tanto el código verdadero como el falso. Para cosas simples como la asignación numérica, esto no es gran cosa. Pero para el código que requiere cualquier tipo de procesamiento, estás perdiendo ciclos ejecutando la condición que no coincide, y posiblemente causando efectos secundarios.

Ilustración 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

Salidas:

Foo!
Bar!
 58
Author: Thomas G. Mayfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-20 09:39:27

También, otro gran problema con el IIf es que en realidad llamará a cualquier función que esté en los argumentos [1], por lo que si tiene una situación como la siguiente:

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

En realidad lanzará una excepción, que no es como la mayoría de la gente piensa que funciona la función la primera vez que la ven. Esto también puede conducir a algunos errores muy difíciles de corregir en una aplicación también.

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

 11
Author: rjzii,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-26 15:43:59

Mejor usar If en lugar de IIf para usar el mecanismo de inferencia de tipo correctamente (Opción Inferir En)

En este ejemplo, las palabras clave se reconocen como una cadena cuando uso If:

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

De lo contrario, se reconoce como un Objeto :

Dim Keywords = IIf(String.IsNullOrEmpty(SelectedKeywords), "N/A", SelectedKeywords)
 7
Author: Larry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-22 12:45:28

De acuerdo con este tipo, IIf puede tomar hasta 6 veces el tiempo que Si/Entonces. YMMV.

 6
Author: Greg Hurlman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-26 15:31:08

Además de eso, la legibilidad probablemente debería ser más preferida que el rendimiento en este caso. Incluso si IIF fuera más eficiente, es simplemente menos legible para el público objetivo (supongo que si estás trabajando en Visual Basic, quieres que otros programadores puedan leer tu código fácilmente, que es la mayor bendición de VB... y que se pierde con conceptos como IIF en mi opinión).

También, "IIF es una función, versus SI es parte de la sintaxis de los lenguajes"... que implica para mí que, de hecho, Si sería más rápido... si por nada más que eso, la sentencia If puede reducirse directamente a un pequeño conjunto de opcodes en lugar de tener que ir a otro espacio en la memoria para realizar la lógica que se encuentra en dicha función. Es una diferencia trillada, tal vez, pero vale la pena señalar.

 6
Author: EdgarVerona,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-26 15:37:33

Creo que la principal diferencia entre If y IIf es:

  • If (test [booleano], statement1, statement2) significa que de acuerdo con el valor de prueba, se ejecutará satement1 o statement2 (solo se ejecutará una instrucción)

  • Dim obj = IIF (test [booleano], statement1, statement2) significa que ambas sentencias se ejecutarán pero de acuerdo con el valor de prueba, una de ellas devolverá un valor a (obj).

Así que si una de las declaraciones throw an exception it will throw it in (IIf) anyway but in (If) it will throw it just in case the condition will return its value.

 6
Author: some guy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-21 14:28:56

{en cuanto a por qué puede tomar tanto tiempo como 6x, cita el wiki:

Debido a que IIf es una función de biblioteca, siempre requerirá la sobrecarga de un función, mientras que un condicional operator will more likely produce código en línea.

Esencialmente IIf es el equivalente de un operador ternario en C++/C#, por lo que le da algunas sentencias de tipo if/else de línea agradable 1 si lo desea. También puede darle una función para evaluar si lo desea.

 5
Author: Dillie-O,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-26 15:34:48

¡Esas funciones son diferentes! Tal vez solo necesita usar la declaración IF. IIF siempre será más lento, porque hará ambas funciones además de la instrucción IF estándar.

Si se está preguntando por qué existe la función IIF, tal vez esta sea la explicación:

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

Así que el contador será 2 después de esto, pero s será "SÍ" solamente. Sé que este contador es inútil, pero a veces hay funciones que necesitarás tanto para ejecutar, no importa si es verdadero o falso, y sólo asignar valor de uno de ellos a su variable.

 1
Author: titol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-16 19:54:19