lunes, 31 de marzo de 2008

Optimizar la carga de un objeto con BeginUpdate

En este post voy a matar dos pájaros de un tiro. Por un lado veremos como cargar un xml de una forma rápida y probaremos una estupenda manera que tiene Visual Basic .Net para hacer que las cargas de los objetos vayan a toda velocidad.

Para ello vamos a utilizar como origen de nuestros datos el xml que generamos el otro día con datos aleatorios (unos 10000 registros de datos). PONER ENLACE

Lo primero que tenemos que hacer es leer el Xml. Aquí existen varias técnicas, pero personalmente me decanto por la siguiente que es bastante sencilla y rápida:

  Dim objXmlDocument As New Xml.XmlDocument
Dim nodos As Xml.XmlNodeList
Dim n As Integer

ComboBox1.Items.Clear()

objXmlDocument.Load("c:\datos.xml")
nodos = objXmlDocument.SelectNodes("/datos/registro")

For n = 0 To nodos.Count - 1
'Cargamos aqui los datos
Next

Como ves lo que se hace es muy simple. Al utilizar el XmlDocument parseamos la entrada de datos (el xml) seleccionando los nodos que cuelgan de /datos/registro. Luego los procesamos en un sencillo for. Internamente XmlDocument carga el xml en forma de árbol, por lo que podemos ir navegando por el (con nodos child, etc.). Algo muy parecido a como se hace en un treeview. Si te gustaría que profundizase en esto y ponga algún ejemplo en el blog lo puedes poner en los comentarios.

Pero seguimos. Ahora nuestro objetivo es cargar los elementos en la combo. Algo tan sencillo como utilizar combobox1.Items.Add. Pero si lo hacemos, veremos que tarda bastante en hacerlo. ¿Y como optimizamos esto? Utilizando BeginUpdate y EndUpdate. Lo que hace BeginUpdate es "congelar" el objeto cuando se llega a esa instrucción, no refrescándolo hasta que encuentra en el EndUpdate. O sea, que realizamos toda la carga si repintar ni refrescar el objeto hasta que terminemos, por lo que la velocidad es mucho mayor. Es algo parecido a utilizar transacciones en sql, pero claro.... a nivel de objeto. Vemos el ejemplo:


Imports System.IO
Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Dim objXmlDocument As New Xml.XmlDocument
Dim nodos As Xml.XmlNodeList
Dim n As Integer

ComboBox1.Items.Clear()

objXmlDocument.Load("c:\datos.xml")
nodos = objXmlDocument.SelectNodes("/datos/registro")

ComboBox1.BeginUpdate()

For n = 0 To nodos.Count - 1
'Cargamos aqui los datos
ComboBox1.Items.Add(nodos.Item(n).InnerText)
Next

ComboBox1.EndUpdate()

End Sub
End Class

Como podreis comprobar la velocidad es muy buena. Para hacer la prueba del algodón basta con que elimineis el BeginUpdate y el EndUpdate. Vereis como se nota la diferencia.

Esto es aplcicable a otros objetos que tiene Visual Basic .Net y yo ya lo utilizo en listviews además de las combobox. Y relamente se nota bastante agilidad y velocidad, sobre todo si tenemos que cargar muchos datos.

No hay comentarios: