La creencia aceptada es que el uso de una construcción como Dim dict As New Dictionary
tiene un rendimiento inferior al Dim dict As Dictionary/Set dict = New Dictionary
.¿Es el mal funcionamiento de Excel VBA la creación automática de un mito?
La explicación es que el ejemplo anterior - auto-instanciación - difiere la instanciación hasta el primer uso de la variable dict
. Y así, cada vez que se hace referencia a dict, el código compilado primero debe verificar si dict
es igual a Nada.
Pero se me ocurre que el código compilado lo hace de todos modos. Obtendrá un error cada vez que intente utilizar una referencia de objeto que sea Nothing
.
Entonces, en homenaje a la ciencia, hice algunas pruebas. Y los resultados sugieren que no hay diferencia de rendimiento entre los dos enfoques. (Ejecutar en Excel 2007)
Llamar "crear diccionario & agregar 2 elementos" 100.000 veces.
- explícitos: 16,891ms/Auto: 16,797ms (94ms Auto más rápido)
- explícitos: 16,797ms/Auto: 16,781ms (16ms Auto más rápido)
Invertir el orden de las llamadas de prueba :
- Auto: 16,766ms/explícitos: 16,812ms (46ms Auto más rápido)
- Auto: 16,828ms/explícitos: 16,813ms (15 ms explícitos más rápido)
Llamar "crear diccionario & agregar 6 elementos" 100.000 veces.
- Auto: 17,437ms/explícitos: 17,407ms (30ms explícitos más rápido)
- Auto: 17,343ms/explícitos: 17,360ms (17ms Auto más rápido)
Crear diccionario y suman 100.000 artículos.
- Auto: 391ms/explícitos: 391ms (SAME)
Crear diccionario y suman 1.000.000 artículos.
- Auto: 57,609ms/explícitos: 58,172ms (563ms Auto más rápido)
- explícitos: 57,343ms/Auto: 57,422ms (79ms explícitos más rápido)
veo nada que indique que la auto-instanciación es una relación de bajo rendimiento para la creación de instancias explícita. (Para que quede claro, por otras razones, evitaría la auto-instanciación, pero estoy interesado en el ángulo de rendimiento aquí).
¿Es esto un mito?
ACTUALIZACIÓN
Permítanme poner por qué el argumento de rendimiento no tiene sentido para mí. Se dice que
x.Add("Key", "Item")
en un objeto de auto-instancia es equivalente a la siguiente:
If x is Nothing then
Set x = New Dictionary
End If
x.Add("Key", "Item")
lo que hace que se vea como "gastos generales aterradora" si está llamando esto miles de veces. Pero en el caso de instancias explícita, es exactamente la forma de la lógica generada en la versión compilada del código:
If x is Nothing Then
Err.Raise "Object variable not set..."
End If
x.Add("Key", "Item")
No significa necesariamente que el auto es más largo, por lo que me estoy preguntando si había cualquier verdad a esto. Me pregunto si he identificado otro de los muchos mitos de rendimiento no probados.
Realmente solo es la semántica diferente de "Nothing" la que establece 'As New' ligeramente separado de' Dim/Set'. Como dices, la llamada sobrecarga que implica una verificación de tipo de tiempo de ejecución es irrelevante dado que, a menos que el objeto verificado automáticamente * sea * 'Nada', no ocurre más que si fuera una referencia' Dim/Set'. –
@Alex K, esta antigua guía de rendimiento dice * cada * referencia a la variable invocará una comprobación "Si X no es nada" en el caso automático, que una variable Dim/Set no mostrará. Por lo tanto, debe probar si se produce un golpe de rendimiento cada vez que acceda al objeto después de la declaración, en lugar de probar la declaración en sí. –
@JP No es cierto. Busqué en Google esto después de otra pregunta que estaba viendo hoy. Ejemplo: http://www.cpearson.com/excel/classes.aspx Otro ejemplo: http://www.bettersolutions.com/vba/VUA113/LI912711911.htm –