November 2008 - Artículos

Hoy me he topado de repente, con una herramienta desconocida para mí y que creo que podría resultarle útil a más de una persona.
Esa herramienta se llama Silverlight Spy, y está desarrollada por Koen Zwikstra.
Silverlight Spy, nos permite inspeccionar cualquier aplicación Silverlight, permitiendo ver la aplicación Silverlight incrustada dentro de una página Web, mostrando la estructura de la aplicación dentro del navegador Web.
Esta herramienta, sólo está pensada para Silverlight 2.0 (no está soportado Silverlight 1.0), y podrá ser descargada a través de ClickOnce desde este enlace.


A la hora de trabajar con Microsoft Office 2007, es posible que nos encontremos con la necesidad de pasar un documento a formato pdf o a formato xps.
Para hacer esto, bastará con instalar el complemento de Microsoft Office 2007 que nos permitirá convertir el documento de Office 2007 a pdf.
Y es que existen muchos complementos para Office 2007, muchos de ellos desconocidos por una gran mayoría, como el complemento Microsoft Math para Microsoft Word 2007.
Y aquí aparece en escena el formato odf (OpenDocument), y que es utilizado como documento estándar para almacenar documentos de ofimática en general.
El formato de odf [información adicional] es muy similar al formato de Office 2007, de hecho, si cambiamos la extensión de este archivo a zip, podremos acceder a los documentos XML que lo forman. El desarrollo de este tipo de documentos ha corrido a cargo de OASIS (Organization for the Advancement of Structured Information Standards).
Muchos recordarán incluso las luchas acerca de la estandarización del formato de Office 2007 comparándolo con odf.
En cualquier caso, en SourceForge tenemos la posibilidad de descargarnos un complemento, que actualmente está en versión 2.5 a fecha del 17 de noviembre de 2008, y que nos permite no solo abrir un documento odf con Office 2007, sino también guardar un documento Office 2007 a formato odf.
La descarga de este complemento la encontrarás en este enlace.
La descarga directa del complemento para Office 2007 versión 2.5 en inglés lo encontrarás en este enlace (4 Mb).
Espero que todo esto le resulte útil a más de una persona.
Microsoft ha liberado una interesante información de su producto en nombre clave Geneva, que consiste en una plataforma para acceso de usuarios simplificado bajo demanda.
La información que ha liberado Microsoft consiste en Geneva Framework para desarrolladores de .NET, Geneva Server para los profesionales de IT, y Windows CardSpace Geneva para los usuarios.
Para entendernos, Geneva no es otra cosa que el nombre en clave de lo que sería la siguiente versión de Microsoft CardSpace, la cual fue anunciada en el último PDC 2008 del que muchos habéis oído ya muchas cosas que presumiblemente aparecerán durante los próximos años.
Un gráfico de Microsoft que he encontrado por Internet que resume dónde encajaríamos a Geneva es el que os indico a continuación (una imagen vale más que mil palabras):

Geneva aceptará los estándares más extendidos y utilizados en las empresas, estándares como WS-Trust, WS-Federation y SAML 2.0.
Encontrarás las descargas de las tres partes principales que citaba en esta entrada en este enlace.
También podrás acceder a la información que publica el equipo de trabajo de Geneva en su blog en este otro enlace.
Ahora solo nos queda empezar a "jugar".
Cuando estamos trabajando en un proyecto del tipo que sea, por ejemplo en un proyecto Software, es inevitable que se den circunstancias que podríamos catalogar inicialmente como negativas. A esas circunstancias negativas, muchos las llaman con el sobrenombre de... ¡PrObLeMaS!.
En sí, cuando ocurre un problema, se debe actuar por ejemplo de la siguiente manera (esta es una forma general de actuación, no es la piedra angular de ninguna forma exacta de cómo actuar):
-
Deberemos catalogar el problema de acuerdo a su importancia. Eso se logra realizando un estudio del posible problema. Es decir, clasificando el problema. Ni todo es grave, ni todo leve. Cada situación debe ser analizada de forma independiente a cualquier otra que haya ocurrido previamente.
-
Deberemos adecuar la resolución del problema a los recursos y valores humanos con los que contamos. Si no contamos con ningún valor humano ni ningún recurso, vamos apañados.
-
Debemos analizar el problema de manera profunda. Es decir, debemos diagnosticar el problema y tomar las acciones necesarias para resolver el problema.
En consecuencia, esas circunstancias negativas podrían llevar anexadas cuál apéndice, una etiqueta de colores muy diversos según su gravedad o la importancia que le demos,... amarilla, naranja o roja.
La etiqueta verde no está catalogada en las anteriores e indica exactamente lo que significa su color. Todo precioso, como la Primavera. Es decir, el resultado esperado e ideal en el que los pajarillos canturrean y las flores buscan los rayos del sol.
-
Una etiqueta de color amarilla seria en consecuencia la más agradable a la vista después de la etiqueta verde o de la normalidad. Pequeñísimos contratiempos que hacen agrandar los ojos y acelerar tímidamente el pulso cardiaco, y que se solventan en un tiempo mínimo. Bien sabemos que representan pequeñas piedras en el camino que aunque molestan y no gustan, no son un claro impedimento. Aquí tiene sentido la frase: "¡Vaya despiste!".
-
Las etiquetas naranjas por su parte, nos obliga a conectar 4 sentidos y medio al ser humano, y por lo general, lo vemos más cerca del color rojo que del color amarillo (cuestión de psicología). Este tipo de etiquetas no nos hace ni pizca de gracia lógicamente, y ya no son meras piedrecitas en el camino, sino que el tamaño de la piedra la definiríamos como "pedrolo", y esos pedrolos nos obligarían a sortearlas casi como dice el presidente del gobierno en España Zapatero... "como sea". Aquí tiene sentido la frase: "¡Macagoentó!".
-
Las etiquetas de color rojo son las etiquetas que nadie quiere ver ni en pintura, a excepción de los Ferrari en la Fórmula 1 y poco más. Aquí se dan las circuntancias más curiosas para un ser humano. Si tuviéramos 20 sentidos, los pondríamos todos a funcionar al mismo tiempo, pero la pena es que sólo tenemos 5 sentidos y debemos acostumbrarnos a trabajar con ellos... en donde no hay no se puede sacar, así que el resto de los sentidos nos los inventamos los seres humanos que somos muy listos para complicarnos más la vida: gritos, nervios, carreras, preocupación, excitación, tensión, estrés, ansiedad,... Aquí tiene sentido la frase: "¡Vaya cagada!".
Y en todo esto la pregunta sería: ¿Un problema sea del tipo que sea es realmente un problema o es una oportunidad?.
Sé que no todo el mundo va a estar de acuerdo conmigo o que no todo el mundo lo va a ver igual, pero quién me conoce, quizás me haya oído decir alguna vez que los problemas no existen. Tan solo existen las contigencias, los contratiempos y los riesgos, pero no los problemas. En sí, un "problema" contratiempo podemos verlo como el vaso medio lleno o como el vaso medio vacío. El "problema" contratiempo no es o no debe ser algo negativo, o no deberíamos abordarlo como algo negativo sino que deberíamos abordarlo como lo que es, una oportunidad. El cerebro tiende a negativizar por lo general aquellas circunstancias que se nos escapan un poco de nuestro control, de ahí, que cuando aparece un bug en la aplicación por ejemplo, nos ponemos a temblar primero, y a llorar después si la etiqueta tiene un tono rojizo.
El cambio de chip que comento sé que no es sencillo, y lo admito, pero es cuestión de connotación gramática y una parte mental o psicológica si quiere expresar mejor. Es quizás una discusión parecida a la de decir recursos humanos en lugar de gestión de personal, o hablar de recursos en lugar de personas.
De todos los modos, hablar de problemas u oportunidades no responde tan solo a un problema gramatical. En sí, encierra más aspectos.
Uno de los principales bajo mi punto de vista es que se requieren acciones proactivas y no reactivas. Esto lo repito hasta la saciedaz, pero no todo el mundo lo entiende así. Por expresarlo de otra forma, yo no suelo ponerme la tirita antes de la herida, me parece absurdo, pero para que quede más claro, si voy a trabajar por ejemplo cortando maderas, sé que hay un riesgo en mi trabajo y lo que sí me pondré son unas gafas para evitar que una astilla pueda saltar y clavárseme en el ojo.
Personalmente, me gusta ser excesivamente proactivo a ser extraordinariamente reactivo, siempre y cuando la situación lo permita claro está.
De esta manera, la primera y principal acción proactiva previa necesaria y obligada en todo desarrollo Software son los test o pruebas unitarias, y éstos son responsabilidad nuestra. Cuando digo nuestra, no digo del jefe de proyecto, o del analista, o del programador, o... ¡no!. me refiero a responsabilidad de todo el equipo de trabajo. Mis "cagadas" si se me permite la expresión, repercuten en todo el proyecto, y por lo tanto en todo el equipo.
Otra tarea a tener en cuenta, es nutrir al desarrollo de los mecanismos suficientes y necesarios (gestión de excepciones y sus políticas, monitoring, logs, etc) para permitir ejecutar o facilitar en la manera que sea posible, las actuaciones sobre los contratiempos que antes enumeraba: clasificación del problema, adecuar la resolución del problema a los recursos y valores humanos con los que contamos, y diagnosticar el problema y tomar las acciones necesarias.
Debemos hacer todo lo posible por evitar que surjan esas piedras en el camino (sean del tamaño que sean) que nos harán retrasarnos, pero cuando ocurre un contratiempo, debemos pensar en que éste va a representar una oportunidad para que hagamos mejor las cosas (mejora, aprendizaje y optimización), que lo podemos utilizar para aprender cosas que hemos hecho de forma incorrecta (experiencia), y que una vez detectada la contingencia, si se le aplica la medida correctora adecuada podremos estar seguros de que no volverá a ocurrir (resolutivo).
¿Estaremos libres de contratiempos aún haciendo pruebas unitarias y aplicando técnicas que faciliten información de qué está pasando, dónde y cómo?. No, las pruebas unitarias deben estar bien hechas al igual que la información que se pueda extraer de la ejecución de las aplicaciones Software. La información que se puede extraer debe tener cierta "lógica" y debe informaros de forma fidedigna del hecho acaecido.
¿Y si las pruebas unitarias y los mecanismos de análisis están bien hechos?. Nunca debemos confiarnos... como me gusta decir muchas veces, "la informática es la única ciencia inexacta del Universo". De hecho, puede pasar incluso que no hayamos recogido los requerimientos adecuadamente, pero si los requerimientos están bien recogidos, se utiliza una metodología acorde y se ponen los mecanismos proactivos adecuados, habremos reducido bastante esos contratiempos.
Aún y así, en el caso de que aparezcan esos contratiempos (que seguro que aparecerán), se deben tratar como lo que son, oportunidades.
Hay muchas premisas más y tampoco quiero extenderme más de lo que ya lo he hecho.
Estas reflexiones han surgido en parte porque en el penúltimo evento de MAD.NUG se preguntó a los asistentes si se hacían pruebas unitarias, y tristemente observé que las pruebas unitarias las hacían menos personas de las que en realidad me esperaba. O todo el mundo hace un Hola Mundo que no requiere pruebas unitarias, o no hemos recogido el significado exacto de u importancia. Y eso... sí es un problema.
Pero bueno, lo que me gustaría recoger aquí también, es el feedback y experiencias personales de lo que pensais sobre esto que comento.
¿Qué opinas?. ¿Piensas realmente que los problemas son problemas o que son oportunidades?. ¿Piensas que son problemas algunas veces y oportunidades en otras ocasiones?. ¿Piensas que ni son problemas ni oportunidades?. ¿Qué piensas al respecto?.
Para empezar la semana, aquí va un video de la "cara oculta del PDC", o lo que es lo mismo... un video de cómo se preparó la Keynote del PDC... es en mi opinión,... increíble y muy curioso.
Espero que aguanteis los casi 6 minutos del video, merecen la pena. ;-)
Tampoco os perdais la cantidad de pruebas que hacen con las pantallas antes de comenzar el evento (y supongo que con el sonido). ¡Eso sí son test unitarios bien hechos!.

A finales del mes pasado os comentaba en otra entrada que Microsoft había liberado la versión Beta 1 de su documentos de buenas prácticas Application Architecture Guide 2.0.
En esta ocasión, os traigo la noticia de la aparición de la versión Beta 2 de ese documento.
El documento, en inglés, tiene un tamaño de 2.7 Mb y está en formato pdf.
Se trata como dije en la entrada anterior a esta, un documento "o libro" de obligada lectura.
Las 365 páginas de este imprescindible libro está dividida en 5 partes y diferentes capítulos dentro de cada parte.
Los 5 bloques o partes principales son:
-
Parte 1: Fundamentals
-
Parte 2: Design
-
Parte 3: Layers
- Parte 4: Archetypes
No he podido revisarlo aún, pero con respecto a la Beta 1, creo que a simple vista resalta que la Parte 4: Quality Attributes ha sido eliminada y se ha metido dentro de la Parte 2. La Parte 5 es ahora la Parte 4.
Conviene recordar, que el documento está aún en fase Beta y sujeto a cambis ya ajustes.
Podemos acceder al documento desde este enlace.
Más información sobre Application Architecture Guide 2.0 en este otro enlace.
Acceso a la página oficial de MAD.NUG.
El próximo 20 de noviembre de 2008 MAD.NUG tiene la suerte de contar no con 1,... sino con ¡¡¡2 eventos!!!. Un día para saciar el apetito del más Geek.
Primer evento: 20 de noviembre de 2008 de 9:00 a 12:30
Con el título de VB/VS Spanish Tour, tenemos la suerte de contar en Madrid (concretamente en Getafe), con los equipos de producto de Visual Studio y Visual Basic. Las personas que vienen están directamente implicadas en Visual Studio y Visual Basic, y vienen desde Redmond (USA) aprovechando el reciente Tech·Ed de Europa que se ha celebrado en Barcelona.
Es una fantástica oportunidad para preguntar esas cosas que nunca te atreviste a preguntar, o de simplemente conocer de primera mano algunas de las novedades o aspectos destacables de Visual Studio desde la versión 2005 hasta lo más reciente que se acerca en Visual Studio 2010, así como de Visual Basic y sus características más interesantes.
Este evento es de carácter gratuito y técnico, en inglés, y dividido en dos sesiones de una duración aproximada de tres horas.
Aunque parezca un evento destinado para desarrolladores de VB, los desarrolladores de C# podrán sacar mucho provecho de este evento debido a que las novedades de Visual Basic y C# son muy parejas, por lo que las novedades que afectan a uno, afectan al otro de igual manera.
La dirección para acudir al evento es la siguiente:
Centro de Formación en Tecnologías de la Información y las Comunicaciones.
C/ Arcas del agua s/n, Getafe (Madrid)
Getafe Madrid 28905
España
La agenda del evento es:
09:15 - Recepción
09:30 - Bienvenida
09:45 - VB 2005, VB 2008 and VB 2010 IDE
XML Literals
11:00 - Cofee Break
11:15 - VB 2010 Language features
LINQ to ADO/SQL & Objects
Interop Toolkit & PowerPacks
12:30 - Q & A
Podrás registrarte para este evento en este enlace.
Segundo evento: 20 de noviembre de 2008 de 19:00 a 21:00
Como no hay dos sin tres, la mejor forma de completar el día es que por la tarde, alguien de Microsoft nos "amenice" con esas "cosas" nuevas o recientes que han llegado del PDC que se celebró en Los Ángeles hace muy pocas fechas. Cosas que todo el mundo ha oído comentar a diestro y siniestro.
David Salgado (Microsoft DPE España) nos hablará (en español) en este evento sobre el PDC Highlights, es decir, de esas cosas que hemos oído contar pero que a lo mejor no terminados de encajar del todo en el puzzle de tecnologías Microsoft... ¿seguro que no?,... ¡pues que no se diga!, porque ahora tenemos la oportunidad de encajar esas piezas de primera mano gracias a David, que estuvo presente en el mismo PDC.
La dirección para acudir al evento es la siguiente:
Microsoft Ibérica, S.R.L.
Sala Marie Curie
Pº del Club deportivo, 1 Centro empresarial La Finca- Edificio 1
Madrid Madrid 28223
España
La información del evento es:
El PDC es un evento internacional de Microsoft donde se presenta el futuro de muchos productos, herramientas y frameworks.
En esta sesión intentaremos dar un repaso a los anuncios más relevantes para el colectivo de desarrolladores.
Ponente: David Salgado
Development Evangelist. Microsoft Iberica
¿Sigues pensando en no venir?. ;-)
Podrás registrarte para este evento en este enlace.
Introducción
En mi última entrada, hacía referencia al porqué puede resultar positivo eliminar la referencia al ensamblado Microsoft.VisualBasic.dll en nuestros proyectos de Visual Basic. Lo cierto es que estas cosas no las encuentras en los libros ni te las cuentan prácticamente nadie, porque simplemente, muchas veces no nos cuestionamos algunas cosas. De vez en cuando es bueno preguntarse el porqué y cómo funcionan las cosas, más que dar por hecho una verdad absoluta.
De acuerdo al título de la entrada, en realidad eliminar tal y como pongo en la entrada es quizás una palabra demasiado drástica, pero es lo suficientemente drástica como para llamar la atención, que es lo que precisamente busco, pero quizás lo más razonable sería decir por ejemplo, tratar de evitar el uso de Microsoft.VisualBasic.dll siempre que podamos en lugar de eliminar, pero aún y así, lo más interesante es describir lo nocivo que puede ser resultar el uso de Microsoft.VisualBasic.dll en nuestros proyectos. Cuando llegue a las conclusiones de esta entrada, pregúntese si realmente está más de acuerdo con la palabra eliminar o con la frase evitar el uso, y sobre todo, pregúntese porqué.
No obstante, para sostener la afirmación de mi primera entrada realicé unos primeros y pequeños estudios que ahora trato de completar con un giro de tuerca más sobre el uso de buenas prácticas, las clases, las funciones y los métodos que .NET nos ofrece y que muchas veces obviamos en nuestros desarrollos Software.
Recordando los resultados del estudio anterior...
Para esta entrada, me baso en el estudio diferencial existente entre el ensamblado que usa Microsoft.VisualBasic.dll y el ensamblado al que hemos eliminado el uso de esta librería que vimos en la entrada anterior.
Adicionalmente, me apoyo en otro estudio y buenas prácticas que realicé en una entrada de Diciembre de 2006 y que podeis encontrar aquí esta entrada. En esa entrada, argumentaba un estudio sobre la iteración de cadenas en nuestras aplicaciones .NET. Argumentos y estudios que me sirven ahora para argumentar más aún algunas tesis que según mi modesto punto de vista, no son nada despreciables y que muestran las bondades de .NET vs el uso de instrucciones de Visual Basic 6 utilizadas en .NET.
Para tratar de ser justos, he vuelto a repetir las pruebas con JetBrains dotTrace que hice en la entrada anterior y he obtenido los siguientes datos:
La hebra de la aplicación (DatosCon) que utiliza el ensamblado que posee referencias a Microsoft.VisualBasic.dll tarda en total 21.722 ms, y en el proceso del control Button, 20.037 ms.
La hebra de la aplicación (DatosSin) que utiliza el ensamblado que no posee referencias a Microsoft.VisualBasic.dll tarda en total 17.692 ms, y en el proceso del control Button, 15.561 ms.
Es decir, la diferencia entre la hebra del primer (DatosCon) y segundo proceso (DatosSin) es de 4.030 ms. 4 segundos son muchos segundos.
Estudiando un poco más a fondo todos estos resultados, lo verdaderamente importante no es la comparación de la ejecución de la hebra completa, ya que el proceso entero está basado en hacer el clic manualmente sobre el control Button, y es posible que esa diferencia de milisegundos esté motivada por mi reacción y pulso más que otra cosa.
Así que donde me quiero parar realmente es en el estudio de la hebra del control Button, que es la que realmente me intesa.
Ahí, la diferencia entre ambos procesos es de 4.476 ms a favor de (DatosSin), es decir, el proceso de ejecución que utiliza el ensamblado que no tiene referencia a Microsoft.VisualBasic.dll es casi 4 segundos y medio más rápido que el mismo proceso de (DatosCon). Si miramos las pruebas que hice de la entrada anterior, la diferencia entre ambos procesos es de 4.465 ms, así que ms arriba ms abajo, estamos más o menos dentro de esos márgenes.
Girando la tuerca un poco más...
Pero claro... aquí no acaba esto, ya que lo más sensato es comparar los dos ensamblados.
Me parece estupendo que uno de ellos "gane", pero ¿estamos seguros de que el ensamblado "ganador" es un ensamblado "perfecto"?.
Yo siempre digo que no hay nada perfecto, y cuando se habla de tecnología muchísimo menos. De hecho, lo voy a demostrar.
Utilizando nuevamente la herramienta JetBrains dotTrace, soy capaz de comparar ambos estudios y ver donde están los "cuellos de botella" o esas diferencias más notables.
En la siguiente imagen, podemos ver esas diferencias de forma gráfica:

Si atendemos a esta información, podremos observar que hay diferentes partes que están en color rojo.
Examinando todas las partes, nos damos cuenta de que hay una parte de la información que nos resulta llamativa. Me refiero a la parte del método TestConversion.

Según ese método, en el caso del uso de la librería WithoutReference.dll, el método que se ejecuta dentro del clic del control Button, consume la friolera cantidad de 15.539 ms de los 15.561 ms que consume todo el código contenido en el control Button.
Para estar utilizando funciones de .NET, el resultado no es que digamos esperanzador, por lo que lo primero que debemos hacer es estudiar el código de ese método.
Estudiando el código y aportando soluciones...
El método TestConversion tiene la funcionalidad de concatenar cadenas.
Concatenar cadenas es mucho más costoso que utilizar por ejemplo la clase StringBuilder que encontraremos en el nombre de espacio System.Text.
De acuerdo a la entrada que escribí en Diciembre del 2006 en el que mostraba la forma eficiente de trabajar con cadenas, deberíamos modificar el código de nuestra aplicación, para mejorar aún más el rendimiento del ensamblado que no utiliza Microsoft.VisualBasic.dll. El objetivo: crear un ensamblado lo más eficiente posible.
De esta forma, el código de nuestro ejemplo de acuerdo al método TestConversion, quedaría de la siguiente forma:
WithoutReference.Class1 (Class1.vb):
|
...
Public Sub TestConversion() Dim auxiliarText As New System.Text.StringBuilder For i As Integer = 0 To 10000 If i Mod 2 = 0 Then ' Convert to String auxiliarText.Append(Convert.ToInt32(i).ToString) Else ' Convert to Integer (Int32) auxiliarText.Append(Convert.ToString(i)) End If Next End Sub ... |
Si prestamos atención al código anterior, veremos que lo que hacemos es apoyarnos en la clase StringBuilder para realizar el mismo proceso.
En este punto, podría preguntarse si podríamos utilizar StringBuilder en el ensamblado que hace referencia a Microsoft.VisualBasic.dll. La respuesta es sí, por supuesto, pero si va a utilizar este objeto propio de .NET, ¿porqué no utiliza desde el principio solo y únicamente los objetos propios de .NET?. Se ahorraría problemas seguramente.
De hecho, el "cuello de botella" del ensamblado que hace uso de Microsoft.VisualBasic.dll está localizado dentro del mismo método, por lo que si utilizáramos StringBuilder, es prácticamente seguro que obtendríamos unos resultados muy óptimos, pero le aseguro, que los resultados más óptimos se encuentran localizados en el ensamblado que no hace uso de Microsoft.VisualBasic.dll. De todos los modos, aquí lo que tratamos de comparar son las funciones y métodos propios de Microsoft.VisualBasic.dll vs las funciones y métodos propios de .NET.
Si una vez modificado el código anterior ejecutamos nuestra aplicación, obtendremos unos resultados sorprendentes.
Estudiando los resultados...
De acuerdo a los nuevos resultados obtenidos, estos arrojan unos datos demoledores a favor de las instrucciones de .NET.
En la siguiente imagen podemos ver la tabla de resultados:

Ahora y gracias a StringBuilder, podemos indicar que la ejecución total de la hebra es de 1.932 ms, mientras que la ejecución del control Button que contiene todas las instrucciones que nos importan, es de 795,4 ms. Ni siquiera 1 segundo. Dentro de esta parte, seguimos observando que TestConversion sigue consumiendo gran parte del tiempo de proceso de ejecución, pero hemos pasado de 15.539 ms a 772,6 ms.
La diferencia es notable evidentemente.
Sobre ILDASM...
Utilizando la herramienta ILDASM que viene con .NET Framework y que permite estudiar el código intermedio de nuestras aplicaciones, podemos apreciar que las diferencias reales entre los dos ensamblados (el ensamblado que tiene la referencia a Microsoft.VisualBasic.dll y el ensamblado que no tiene referencia a ese ensamblado) son mínimas.
Si se estudia con detenimiento el código intermedio, se pueden ver algunos pequeños detalles en el ensamblado con referencia a Microsoft.VisualBasic.dll que no tiene el otro ensamblado, como algún ajuste de conversión.
De todos los modos, lo mejor es utilizar .NET Reflector y mirar las clases, métodos y funciones de Microsoft.VisualBasic.dll, y comprobar como funciona realmente "por debajo".
Algunas conclusiones...
-
Ante esto tenemos una opción muy clara y evidente con una afirmación mucho más drástica si cabe: el uso exclusivo de Microsoft.VisualBasic.dll no nos favorece. Es decir, si lo que queremos es utilizar únicamente instrucciones de Microsoft.VisualBasic.dll, es prácticamente seguro que penalizaremos en rendimiento a nuestra aplicación. ¿Cuál es la penalización?. En realidad depende de cada proyecto, del código escrito en él, sus iteraciones, etc.
-
El uso híbrido de Microsoft.VisualBasic.dll e instrucciones puras .NET puede resultarnos útil y ventajoso. No es quizás lo más ventajoso, pero es claramente más favorable que el uso único y exclusivo de instrucciones heredadas de Visual Basic 6.
-
Si decidimos por un híbrido entre instrucciones puras .NET e instrucciones extraídas el ensamblado Microsoft.VisualBasic.dll, ¿porqué no utilizar directamente y únicamente las instrucciones de .NET?. Ese sería el escenario más adecuado y positivo. Por esa razón, una forma de habituarnos a trabajar sin el ensamblado Microsoft.VisualBasic.dll en Visual Studio 2008, es acceder a las Propiedades del proyecto y abrir la solapa de Referencias. Dentro de esa solapa, quitar la selección o la referencia al ensamblado Microsoft.VisualBasic.dll. De esta manera, el entorno nos avisará con un mensaje de error si estamos utilizando alguna instrucción de Visual Basic 6 habilitada por medio de Microsoft.VisualBasic.dll.
Así, ¿cuantas veces utiliza (yo lo hago) la instrucción VbCrLf?. Pues quizás no lo sepa, pero VbCrLf pertenece a la clase Contants del nombre de espacio Microsoft.VisualBasic. ¿Sorprendido?. Quizás lo lógico es utilizar \r\n en C#, o Environment.NewLine() en .NET, ¿pero VbCrLf?.
Como podemos ver, los "vicios" adquiridos y arrastrados por los desarrolladores que venimos de Visual Basic 6.0 son muchos, y erradicarlos va a ser un proceso muy largo y tedioso. ¿Porqué no empezar desde ya?.
Introducción
En la última entrada de mi blog, escribí acerca de como eliminar la referencia al ensamblado Microsoft.VisualBasic.dll de nuestros proyectos.
En esa entrada, hubo algunas personas que dieron sus opiniones dentro del apartado de comentarios, algo que agradezco muchísimo, ya que siempre es importante la interactuación de la gente en un blog donde no suele haber un diálogo, sino un intercambio de opiniones o puntos de vista, y los razonamientos y pensamientos se hacen a trompicones.
Las dudas razonables...
Dentro de esos comentarios hubo uno iniciado por delm en el que afirmaba que le daba mucha lástima que se gastara energía en investigar cosas como la que indicaba en mi entrada, y dudaba que esos esfuerzos sirvieran para algo.
Desde luego, que cualquier investigación o análisis sirve, incluso si las conclusiones de esos estudios son nulos. Es positivo que se realicen estudios de todo tipo (con cierto criterio claro está) con el fin de aprender más acerca de las tecnologías y su uso.
Pero no solo es positivo en el campo de la investigación y su uso, sino que a veces es incluso hasta importante u obligatorio.
Por esa razón supongo, delm nos comentaba igualmente que se fundamentara las afirmaciones que se realizan en mi entrada con estudios o profiling en una o varias aplicaciones de un tamaño decente para ver si realmente vale la pena.
A mí me gustaría por otro lado, que delm también realizara esos estudios para fundamentar sus opiniones contrarias. Así nos enriqueceríamos todos.
No obstante, yo ya hice algunos estudios sobre esto hace tiempo, pero ni los tenía a mano, ni sinceramente, me encontraba con ganas de repetirlos debido al poco tiempo libre que tenía para hacer unos estudios concienzudos. Sin embargo, he sacado algo de tiempo para escribir esta segunda entrada y comentar un pequeño y espero que simbólico estudio que he hecho con el fin u objetivo de demostrar el porqué puede ser interesante eliminar al referencia de Microsoft.VisualBasic.dll y usar en su lugar las librerías de .NET.
Lo más sensato es hacer un estudio muchísimo más riguroso, pero espero que este pequeño estudio ofrezca algo de luz a quienes dudan de si es positivo o no eliminar la referencia a Microsoft.VisualBasic.dll.
Recordando...
Recordad, que cuando se llama a un método o función de Microsoft.VisualBasic.dll, ésta se convierte a su método o función equivalente dentro de .NET, lo cuál genera de alguna manera ciertas penalizaciones en el rendimiento de nuestras aplicaciones.
Demostrando...
La pequeña demostración (siento mucho no haber podido hacer una demostración mucho más completa como me hubiera gustado) es la siguiente:
He creado dos clases exactamente iguales en funcionalidad, aunque distintas en cuanto al código escrito, ya que una de ellas se basa en las funciones de VB 6 de Microsoft.VisualBasic.dll y el otro código, se basa en las funciones propias de .NET.
Para estudiar el profiling, me he apoyado en la herramienta JetBrains dotTrace.
Y así, empezamos a codificar la primera clase que he llamado WithReference.
El código de esta primera clase con funciones típicas de VB 6 para .NET es el siguiente:
WithReference.Class1 (Class1.vb):
|
Namespace WithReference
Public Class Class1
Public Function DeleteSpaces(ByVal data As String) As String Return Trim(data) End Function
Public Function TakeLeftRightText(ByVal data As String) As String Return Left(data, 1) & Right(data, 1) End Function
Public Function TransformTextMid(ByVal data As String) As String Dim auxiliarText As String = "" For I As Byte = 1 To Len(data) auxiliarText &= Mid(data, I, 1) Next Return auxiliarText End Function
Public Function TransformTextReplace(ByVal data As String, _
ByVal findCharacter As String, ByVal replaceCharacter As String) As String Return Replace(data, findCharacter, replaceCharacter) End Function
Public Function TransformTextReverse(ByVal data As String) As String Return StrReverse(data) End Function
Public Function TransformTextUpper(ByVal data As String) As String Return UCase(data) End Function
Public Function TransformTextLower(ByVal data As String) As String Return LCase(data) End Function
Public Function GetCharacterPosition(ByVal data As String, ByVal searchText As String) As Byte Return InStr(data, searchText) End Function
Public Sub TestConversion() Dim auxiliarText As String = "" For i As Integer = 0 To 10000 If i Mod 2 = 0 Then ' Convert to String auxiliarText &= Conversion.Int(i).ToString Else ' Convert to Integer (Int32) auxiliarText &= Conversion.Str(i) End If Next End Sub
End Class ' Class1
End Namespace ' WithReference
|
A la segunda clase la he llamado WithoutReference.
El código de la segunda clase con funciones propias de .NET equivalentes a las usadas en la clase anterior es el siguiente:
WithoutReference.Class1 (Class1.vb):
|
Namespace WithoutReference
Public Class Class1
Public Function DeleteSpaces(ByVal data As String) As String Return data.Trim End Function
Public Function TakeLeftRightText(ByVal data As String) As String Return data.Substring(1, 1) & data.Substring(data.Length - 1, 1) End Function
Public Function TransformTextMid(ByVal data As String) As String Dim auxiliarText As String = "" For I As Byte = 0 To data.Length - 1 auxiliarText &= data.Substring(I, 1) Next Return auxiliarText End Function
Public Function TransformTextReplace(ByVal data As String, _
ByVal findCharacter As String, ByVal replaceCharacter As String) As String Return data.Replace(findCharacter, replaceCharacter) End Function
Public Function TransformTextReverse(ByVal data As String) As String Dim charArray(data.Length) As Char For i As Byte = 0 To data.Length - 1 charArray(i) = data(data.Length - (i + 1)) Next Return New String(charArray) End Function
Public Function TransformTextUpper(ByVal data As String) As String Return data.ToUpper End Function
Public Function TransformTextLower(ByVal data As String) As String Return data.ToLower End Function
Public Function GetCharacterPosition(ByVal data As String, ByVal searchText As String) As Byte Return data.IndexOf(searchText, 1) End Function
Public Sub TestConversion() Dim auxiliarText As String = "" For i As Integer = 0 To 10000 If i Mod 2 = 0 Then ' Convert to String auxiliarText &= Convert.ToInt32(i).ToString Else ' Convert to Integer (Int32) auxiliarText &= Convert.ToString(i) End If Next End Sub
End Class ' Class1
End Namespace ' WithoutReference
|
Finalmente he compilado las clases. WithReference con Visual Studio 2008, y WithoutReference siguiendo el patrón de la entrada anterior donde mostraba como compilar una clase con .NET eliminando las referencias a Microsoft.VisualBasic.dll.
La diferencia de tamaños entre las clases son:
- WithReference.dll (11,5 Kb)
- WithoutReference.dll (4,5 Kb)
Además de los tamaños de las clases, existen más diferencias en tiempo de ejecución tal y como veremos a continuación.
Para este experimento, he iniciado una aplicación Windows con C# y con un control Button, al que he agregado una referencia con el ensamblado WithReference.dll.
Dentro del código del formulario windows he escrito el siguiente código:
Aplicación Windows (MainForm.cs):
|
private void btnTestProfiler_Click(object sender, EventArgs e) { this.Text = "Proceso iniciado..."; this.Enabled = false; WithReference.Class1 classTest = new WithReference.Class1(); for (int i = 0; i < 100; i++) { string result; result = classTest.DeleteSpaces(" Testing "); byte position; position = classTest.GetCharacterPosition("Testing", "i"); result = classTest.TakeLeftRightText("Testing"); classTest.TestConversion(); result = classTest.TransformTextLower("ReSuLtS"); result = classTest.TransformTextUpper("ReSuLtS"); result = classTest.TransformTextMid("Text to extract letter by letter"); result = classTest.TransformTextReplace("This is a sample text, to replace it by other different text.", "a", "n"); result = classTest.TransformTextReverse("This is a sample text, to do the reverse of this text."); } this.Text = "Proceso finalizado."; this.Enabled = true; } |
He generado el fichero ejecutable y he copiado el ejecutable y la librería en un directorio aparte.
Una vez hecho esto, he repetido el proceso quitando la referencia a WithReference.dll y agregando una referencia al ensamblado WithoutReference.dll.
El código de la aplicación para este segundo caso es el siguiente:
Aplicación Windows (MainForm.cs):
|
private void btnTestProfiler_Click(object sender, EventArgs e) { this.Text = "Proceso iniciado..."; this.Enabled = false; WithoutReference.Class1 classTest = new WithoutReference.Class1(); for (int i = 0; i < 100; i++) { string result; result = classTest.DeleteSpaces(" Testing "); byte position; position = classTest.GetCharacterPosition("Testing", "i"); result = classTest.TakeLeftRightText("Testing"); classTest.TestConversion(); result = classTest.TransformTextLower("ReSuLtS"); result = classTest.TransformTextUpper("ReSuLtS"); result = classTest.TransformTextMid("Text to extract letter by letter"); result = classTest.TransformTextReplace("This is a sample text, to replace it by other different text.", "a", "n"); result = classTest.TransformTextReverse("This is a sample text, to do the reverse of this text."); } this.Text = "Proceso finalizado."; this.Enabled = true; } |
He vuelto a compilar el proyecto y lo he apartado en otro directorio junto a la librería del ensamblado WithoutReference.dll.
De esta manera, tengo los dos programas listos para ser procesados con la herramienta de rendimiento y profiling.
Estudiando comportamientos...
He arrancado la herramienta JetBrains dotTrace y he ejecutado el primer ejecutable (con el ensamblado WithReference.dll) y he obtenido unos datos muy diferentes a los que muestra el segundo ejecutable (con el ensamblado WithoutReference.dll).
Los datos obtenidos del uso de WithReference.dll los he denominado DatosCon.

Los datos obtenidos del uso de WithoutReference.dll los he denominado DatosSin.

En este punto, lo que tenemos que hacer es estudiar los comportamientos de los dos ensamblados.
En el caso del uso del ensamblado con referencias a Microsoft.VisualBasic.dll, vemos que el proceso de ejecución nos ha durado 24.445 ms, y el proceso principal del control Button, 20.292 ms.
Por su parte, el ensamblado sin referencia a Microsoft.VisualBasic.dll, ha tardado en el proceso general 17.877 ms, mientras que en el proceso principal del control Button, el tiempo que ha tomado es de 15.827 ms.
Algunas conclusiones...
Las conclusiones a simple vista son bastante claras.
El ensamblado que no tiene referencia a Microsoft.VisualBasic.dll, tiene un menor tamaño en su ensamblado y es más rápido en su ejecución.
De todos los modos, tengo pensado agregar alguna entrada más que tendrá por objetivo estudiar algunos de los resultados obtenidos en estas pruebas, y mirar un poco el código intermedio de ambos ensamblados.
Espero que esto, ayude a clarificar aún más mis afirmaciones, las cuales no son verdades absolutas, pero sí pueden ser consideradas por algunos con un poco más de fundamento.