viernes, 12 de junio de 2015

Videos - IoTaConf Octubre 2014

Videos del IoTaConf Octubre 2014

El futuro de la computación es el Internet de las Cosas (IoT), y en este post les comparto los videos de uno de los eventos mas importantes a nivel mundial sobre este tema.

1. Olivier Bloch: Using Microsoft tools and platforms to build the IoT



2. Michael Koster, ARM: Design Patterns for an Internet of Things


3. Todd Montgomery, Kaazing: IoT Connectivity, Standards & Architecture


4. Wayne Piekarski, Google: Android Wear


5. Ravi Kurani, Sutro: 50 Billion Devices and the Next Billion Consumers


6. Bo Huang, SenseEarth: Real world maps in first person with Oculus Rift


7. Alex Lebrurn, Wit.AI: Speech Interfaces for the Internet of Things


8. Abhishek Sanwal: IOT Landscape, Evolution & Marturity Models. Rework the Internet


9. Andy Carle, Marvell: Mind the Gap. JavaScript for IoT, from Concept to Production


10. Kevin Hoyt, Kaazing: IoT and the New Web


11. Oliver Hutaff, Electric Imp: The True Value of the Internet of Things


12. Alfred Lui, Seer Labs: Re-orientating­ UX Design for the Internet of Things


13. Rikard Strid, Clayster: XMPP - Normalize Internet Of Things



El Libro del Día: Rethinking the Internet of Things

El Libro del Día: 2015-06-12

Titulo: Rethinking the Internet of Things
Autor: Francis daCosta
Editorial: Apress
Nro Paginas: 185

Capítulos:
Chapter 1: It’s Different Out Here
Chapter 2: Anatomy of the Internet of Things
Chapter 3: On the Edge
Chapter 4: Building a Web of Things
Chapter 5: Small Data, Big Data, and Human Interaction
Chapter 6: Architecture for the Frontier
Chapter 7: Examples and Applications
Chapter 8: Pathways to the Internet of Things

Descarga:
Rethinking_the_Internet_of_Things

lunes, 8 de junio de 2015

El Libro del Día: Pro Grunt.js

El Libro del Día: 2015-06-08

Titulo: Pro Grunt.js
Autor: James Cryer
Editorial: Apress
Nro Paginas: 165

Capítulos:
Chapter 1: Introducing Grunt
Chapter 2: How to Use Grunt in Your Project
Chapter 3: Using Grunt with HTML and CSS
Chapter 4: Using Grunt with JavaScript
Chapter 5: Using Grunt with Images, SVG, and Icons
Chapter 6: Using Grunt for Testing and Local Development
Chapter 7: Optimizing Your Grunt Workflow

Descarga:
Pro_Grunt.js

viernes, 5 de junio de 2015

El Libro del Día: Practical .NET 2.0 Networking Projects

El Libro del Día: 2015-06-05

Titulo: Practical .NET 2.0 Networking Projects
Autor: Wei-Meng Lee
Editorial: Apress
Nro Paginas: 291

Capítulos:
CHAPTER 1 Sockets Programming
CHAPTER 2 Serial Communications
CHAPTER 3 Incorporating Fingerprint Recognition into Your .NET Application
CHAPTER 4 Infrared Programming
CHAPTER 5 Fun with RFID
CHAPTER 6 Interfacing with External Devices

Descarga:
Practical_.NET_2.0_Networking_Projects

jueves, 4 de junio de 2015

El Demo del Día: Performace entre Serializadores .NET

Performace entre Serializadores .NET

El Problema de la Performance

Uno de los problemas principales de los Sistemas Informáticos Modernos es la Performance, sea Windows o Web la Aplicación, con el crecimiento del uso (aumento de usuarios) dentro (Intranet) y fuera de la empresa (Internet) las aplicaciones cada vez son mas lentas.

Esta lentitud es tratada de resolver aumentando Hardware como mas Servidores, mas Memorias, mas CPUs, mas Ancho de Banda, etc. Todo menos hacer una reingeniería del desarrollo que es la principal causa, es decir el problema es la forma cómo se programa (Software) donde lo común es que se realizan muchas conexiones al Servidor de Base de Datos, se usan estructuras de datos pesadas (por ejemplo en .NET los DataSets), se hacen bucles expensivos, etc.

Solución al Problema de la Performance

Aprender las Buenas Prácticas de Programación que permitan consumir la menor cantidad de memoria con el menor tiempo de procesamiento, para lo cual hay diferentes las cuales compartiremos a partir de hoy, empezando por una Comparación de Serializadores para elegir el mejor.

Definición de Serialización

Según Wikipedia, la Serialización (o Marshalling en inglés) es el proceso de codificación de un objeto en un medio de almacenamiento (como puede ser un archivo, o un buffer de memoria) con el fin de transmitirlo a través de una conexión en red como una serie de bytes o en un formato humanamente más legible como XML o JSON, entre otros.

La serie de bytes o el formato pueden ser usados para crear un nuevo objeto que es idéntico en todo al original, incluido su estado interno (por tanto, el nuevo objeto es un clon del original).

La Serialización es un mecanismo ampliamente usado para transportar objetos a través de una red, para hacer persistente un objeto en un archivo o base de datos, o para distribuir objetos idénticos a varias aplicaciones o localizaciones.

Importancia de elegir un Serializador

Es necesario saber elegir adecuadamente un Serializador, ya que cada vez que enviamos datos entre dos procesos se usa la serialización. 

A continuación listamos los Serializadores .NET junto con los tipos de aplicaciones o tecnologías distribuidas que las usan por defecto:

- Serializador Binario: Usado en Sockets y .NET Remoting (dll)
- Serializador SOAP: Usado por Servicios Web XML (asmx)
- Serializador XML: Usado por los Servicios WCF (svc y dll)
- Serializador JSON: Usado en Web API
- Serializador Personalizado: Hay que crearlo uno mismo.

La importancia de seleccionar bien el Serializador es que este es el factor principal de performance al momento de usar un Servicio o una Aplicación Distibuida, es decir, depende de este el tiempo de serialización deserealización y sobre todo el formato y el tamaño de los datos que se pasan por la red.

En este post, comprobaremos cual es el mejor, sin embargo la mayoría siempre usa el peor y después quiere que sus Servicios sean rápidos, es decir, quieren una cosa (Performance) pero hacen otra (Estándar).

Crear una Aplicación Windows Forms en C#

Abrir Visual Studio y crear una aplicación Windows Forms en C# llamada "Comparacion_Serializacion", cambiarle de nombre al formulario por "frmListaProductos" y realizar el diseño similar a la figura mostrada:


Nota: En el diseño hay un DataGridView llamado "dgvProducto", un menú contextual llamado "mnuContextual" con 6 opciones: mnuCargarDatos, mnuBinario, mnuSOAP, mnuXML, mnuJSON y mnuPersonalizado.

Crear el Procedimiento Almacenado en SQL Server

Crear el Procedimiento llamado "uspProductsListar" en SQL Server:

Create Procedure uspProductsListar
As
Select ProductID, ProductName, SupplierID, 
CategoryID,UnitPrice, UnitsInStock
From Products

Crear la Clase Entidad del Negocio

Agregar una clase al proyecto llamada: "beProducto" y escribir el siguiente código:

using System;
using System.Runtime.Serialization;

namespace Comparacion_Serializacion
{
    //[Serializable]
    //[DataContract]
    public class beProducto
    {
        //[DataMember]
        public int IdProducto { get; set; }
        //[DataMember]        
        public string Nombre { get; set; }
        //[DataMember]
        public int IdProveedor { get; set; }
        //[DataMember]
        public int IdCategoria { get; set; }
        //[DataMember]
        public decimal PrecioUnitario { get; set; }
        //[DataMember]
        public short Stock { get; set; }
    }
}

Nota: Los atributos de serialización (Serializable, DataContract y DataMember) han sido comentados inicialmente para ver que sucede cuando se intenta serializar con cada técnica.

Crear la Clase de Acceso a Datos

Agregar una clase al proyecto llamada: "daProducto" y escribir el siguiente código:

using System;
using System.Collections.Generic; //List
using System.Data; //CommandType, CommandBehavior
using System.Data.SqlClient; //SqlConnection, SqlCommand, SqlDataReader

namespace Comparacion_Serializacion
{
    public class daProducto
    {
        public List<beProducto> listar(SqlConnection con)
        {
            List<beProducto> lbeProducto = null;

            SqlCommand cmd = new SqlCommand("uspProductsListar", con);
            cmd.CommandType = CommandType.StoredProcedure;
            SqlDataReader drd = cmd.ExecuteReader(CommandBehavior.SingleResult);
            if (drd != null)
            {
                lbeProducto = new List<beProducto>();
                int posIdProducto = drd.GetOrdinal("ProductID");
                int posNombre = drd.GetOrdinal("ProductName");
                int posIdProveedor = drd.GetOrdinal("SupplierID");
                int posIdCategoria = drd.GetOrdinal("CategoryID");
                int posPrecioUnitario = drd.GetOrdinal("UnitPrice");
                int posStock = drd.GetOrdinal("UnitsInStock");
                beProducto obeProducto;
                while (drd.Read())
                {
                    obeProducto = new beProducto();
                    obeProducto.IdProducto = drd.GetInt32(posIdProducto);
                    obeProducto.Nombre = drd.GetString(posNombre);
                    obeProducto.IdProveedor = drd.GetInt32(posIdProveedor);
                    obeProducto.IdCategoria = drd.GetInt32(posIdCategoria);
                    obeProducto.PrecioUnitario = drd.GetDecimal(posPrecioUnitario);
                    obeProducto.Stock = drd.GetInt16(posStock);
                    lbeProducto.Add(obeProducto);
                }
                drd.Close();
            }

            return (lbeProducto);
        }
    }
}

Crear la Clase de Reglas del Negocio

Agregar una clase al proyecto llamada: "brProducto" y escribir el siguiente código:

using System;
using System.Configuration; //ConfigurationManager
using System.Data.SqlClient; //SqlConnection
using System.Collections.Generic; //List

namespace Comparacion_Serializacion
{
    public class brProducto
    {
        public string CadenaConexion { get; set; }
        private string archivoLog;

        public brProducto()
        {
            CadenaConexion = 
                ConfigurationManager.ConnectionStrings["conNW"].ConnectionString;
        }

        public List<beProducto> listar()
        {
            List<beProducto> lbeProducto = null;
            using (SqlConnection con = new SqlConnection(CadenaConexion))
            {
                try
                {
                    con.Open();
                    daProducto odaProducto = new daProducto();
                    lbeProducto = odaProducto.listar(con);
                }
                catch (SqlException ex)
                {
                    //grabarLog(ex);
                }
                catch (Exception ex)
                {
                    //grabarLog(ex);
                }
            } //con.Close(); con.Dispose();
            return (lbeProducto);
        }
    }
}

Nota: Para usar la clase "ConfigurationManager", primero hay que hacer referencia a la librería "System.Configuration.dll"

Crear una Clase para la Serialización Personalizada de Strings

Agregar una clase al proyecto llamada: "CustomSerializer" y escribir el siguiente código:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.IO;

namespace Comparacion_Serializacion
{
    public class CustomSerializer
    {
        public static void Serializar<T>(List<T> lista, string archivo, char separadorCampo, 
        char separadorRegistro)
        {
            StringBuilder sb = new StringBuilder();
            PropertyInfo[] propiedades = lista[0].GetType().GetProperties();
            for (int i = 0; i < propiedades.Length; i++)
            {
                sb.Append(propiedades[i].Name);
                if (i < propiedades.Length - 1) sb.Append(separadorCampo);
            }
            sb.Append(separadorRegistro);
            for (int j = 0; j < lista.Count; j++)
            {
                propiedades = lista[j].GetType().GetProperties();
                for (int i = 0; i < propiedades.Length; i++)
                {
                    if (propiedades[i].GetValue(lista[j], null) != null) 
                    sb.Append(propiedades[i].GetValue(lista[j], null).ToString());
                    else sb.Append("");
                    if (i < propiedades.Length - 1) sb.Append(separadorCampo);
                }
                if (j < lista.Count - 1) sb.Append(separadorRegistro);
            }
            File.WriteAllText(archivo,sb.ToString());
        }

        public static List<T> Deserializar<T>(string archivo, char separadorCampo, 
        char separadorRegistro)
        {
            List<T> lista = new List<T>();
            if (File.Exists(archivo))
            {
                string contenido = File.ReadAllText(archivo);
                string[] registros = contenido.Split(separadorRegistro);
                string[] campos;
                string[] cabecera = registros[0].Split(separadorCampo);
                string registro;
                Type tipoObj;
                T obj;
                dynamic valor;
                Type tipoCampo;
                for (int i = 1; i < registros.Length; i++)
                {
                    registro = registros[i];
                    tipoObj = typeof(T);
                    obj = (T)Activator.CreateInstance(tipoObj);
                    campos = registro.Split(separadorCampo);
                    for (int j = 0; j < campos.Length; j++)
                    {
                        tipoCampo = obj.GetType().GetProperty(cabecera[j]).PropertyType;
                        valor = Convert.ChangeType(campos[j],tipoCampo);
                        obj.GetType().GetProperty(cabecera[j]).SetValue(obj, valor);
                    }
                    lista.Add(obj);
                }
            }
            return (lista);
        }
    }
}

Nota: Para crear mi propio Serializador uso Reflection y Listas Genéricas. 
Una de las claves para hacer la Deserealización es crear una instancia del objeto dinámicamente con Activator.CreateInstance y luego escribir el valor desde la cadena al objeto para lo cual uso Convert.ChangeType.

Escribir el Código del Formulario frmListaProducto

Antes de escribir el código de los Serializadores hay que hacer las siguientes Referencias:
- System.Runtime.Serialization.Formatters.Soap.dll para la Serialización SOAP
- System.Runtime.Serialization para la Serialización JSON

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO; //FileStream
using System.Linq; //ToList
using System.Diagnostics; //Stopwatch
using System.Runtime.Serialization.Formatters.Binary; //BinaryFormatter
using System.Runtime.Serialization.Formatters.Soap; //SoapFormatter
using System.Xml.Serialization; //XmlSerializer
using System.Runtime.Serialization.Json; //DataContractJsonSerializer

namespace Comparacion_Serializacion
{
    public partial class frmListaProducto : Form
    {
        private List<beProducto> lbeProducto;

        public frmListaProducto()
        {
            InitializeComponent();
        }

        private void cargarDatos(object sender, EventArgs e)
        {
            brProducto obrProducto = new brProducto();
            lbeProducto = obrProducto.listar();
            dgvProducto.DataSource = lbeProducto;
        }

        private void medirTiempo(Action metodo)
        {
            Stopwatch cronometro = new Stopwatch();
            cronometro.Start();
            metodo();
            MessageBox.Show(String.Format("Tiempo de Duración: {0:n0} msg", 
            cronometro.Elapsed.TotalMilliseconds));
            cronometro.Stop();
        }

        private void serializarBinario()
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream fs = new FileStream("Binario.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                bf.Serialize(fs, lbeProducto);
            }
        }

        private void deserializarBinario()
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream fs = new FileStream("Binario.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto=(List<beProducto>)bf.Deserialize(fs);
            }
        }

        private void serializarSOAP()
        {
            SoapFormatter sf = new SoapFormatter();
            using (FileStream fs = new FileStream("SOAP.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                sf.Serialize(fs, lbeProducto.ToArray());
            }
        }

        private void deserializarSOAP()
        {
            SoapFormatter sf = new SoapFormatter();
            using (FileStream fs = new FileStream("SOAP.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto=((beProducto[])sf.Deserialize(fs)).ToList();
            }
        }

        private void serializarXML()
        {
            XmlSerializer xs = new XmlSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("XML.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                xs.Serialize(fs, lbeProducto);
            }
        }

        private void deserializarXML()
        {
            XmlSerializer xs = new XmlSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("XML.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto = (List<beProducto>)xs.Deserialize(fs);
            }
        }

        private void serializarJSON()
        {
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("JSON.txt",
                FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                js.WriteObject(fs, lbeProducto);
            }
        }

        private void deserializarJSON()
        {
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(List<beProducto>));
            using (FileStream fs = new FileStream("JSON.txt",
                FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                lbeProducto=(List<beProducto>)js.ReadObject(fs);
            }
        }

        private void serializarString()
        {
            CustomSerializer.Serializar(lbeProducto, "Strings.txt", ',', '|');
        }

        private void deserializarString()
        {
            lbeProducto=CustomSerializer.Deserializar<beProducto>("Strings.txt", ',', '|');
        }

        private void mnuSerializarBinario_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarBinario);
        }

        private void mnuDeserializarBinario_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarBinario);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerializarSOAP_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarSOAP);
        }

        private void mnuDeserializarSOAP_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarSOAP);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerializarXML_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarXML);
        }

        private void mnuDeserializarXML_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarXML);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerealizarJSON_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarJSON);
        }

        private void mnuDeserealizarJSON_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarJSON);
            dgvProducto.DataSource = lbeProducto;
        }

        private void mnuSerializarPersonalizado_Click(object sender, EventArgs e)
        {
            medirTiempo(serializarString);
        }

        private void mnuDeserializarPersonalizado_Click(object sender, EventArgs e)
        {
            medirTiempo(deserializarString);
            dgvProducto.DataSource = lbeProducto;
        }
    }
}

Nota: Todos las funciones manejadoras de eventos llaman a la función "medirTiempo" para ejecutar la Serialización y Deserealización.

Modificar el Archivo de Configuración

Abrir el archivo app.Config y aumentar la cadena de conexión:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="conNW" providerName="SQLServer"
      connectionString="uid=UsuarioNW;pwd=123456;
      server=DSOFT\Sqlexpress;database=Northwind"/>
  </connectionStrings>
  <startup> 
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

Ejecutar y Probar la Aplicación Windows Forms

Grabar la aplicación y pulsar F5 para ejecutarla. Aparecerá una ventana similar a la siguiente figura:


Clic derecho y se mostrará el menú contextual, del cual seleccionar la primera opción: "Cargar Datos" y se listarán los productos.


Serialización Binaria

Clic derecho y del menú contextual seleccionar la opción "Binario" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 11 msg y se creará un archivo llamado "Binario.txt" con el siguiente contenido:


Notas: 
- Si se intenta Serializar el archivo a Binario se caerá ya que la Entidad (clase beProducto) no es serializable, proceder a descomentar el atributo [Serializable].
- Observar que el tamaño del archivo Binario.txt es de 5756 bytes (en mi caso).

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 8 msg y se cargarán los datos desde el archivo "Binario.txt" en la lista de objetos y se mostrará en la grilla.

Serialización SOAP

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "SOAP" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 30 msg y se creará un archivo llamado "SOAP.txt" con el siguiente contenido:


Nota: Observar que el tamaño del archivo SOAP.txt es de 73586 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 51 msg y se cargarán los datos desde el archivo "SOAP.txt" en la lista de objetos y se mostrará en la grilla.

Serialización XML

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "XML" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 192 msg y se creará un archivo llamado "XML.txt" con el siguiente contenido:


Nota: Observar que el tamaño del archivo XML.txt es de 22270 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 209 msg y se cargarán los datos desde el archivo "XML.txt" en la lista de objetos y se mostrará en la grilla.

Serialización JSON sin atributos

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "JSON" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 474 msg y se creará un archivo llamado "JSON.txt" con el siguiente contenido:


Nota: Observar que el tamaño del archivo JSON.txt es de 19716 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 347 msg y se cargarán los datos desde el archivo "JSON.txt" en la lista de objetos y se mostrará en la grilla.

Serialización JSON con atributos (DataContract y DataMember)

Detener la ejecución, decomentar los atributos [DataContract] y [DataMamber] de la entidad beProducto, además renombrar el archivo JSON.txt por JSON2.txt y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "JSON" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 27 msg y se creará un archivo llamado "JSON.txt" con el siguiente contenido:



Nota: Observar que el tamaño del archivo JSON.txt es tan solo de 10332 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Binario" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 92 msg y se cargarán los datos desde el archivo "JSON.txt" en la lista de objetos y se mostrará en la grilla.

Serialización Personalizada con Strings

Detener la ejecución y probar nuevamente, seleccionando la opción "Cargar Datos", luego del menú contextual seleccionar la opción "Personalizado" y luego "Serializar", se mostrará el tiempo de la serialización, en mi caso 15 msg y se creará un archivo llamado "Strings.txt" con el siguiente contenido:



Nota: Observar que el tamaño del archivo Strings.txt es de 3125 bytes (en mi caso)

Detener la ejecución y probar nuevamente, pero esta vez seleccionar directamente del menú contextual "Personalizado" y "Deserealizar", se mostrará el tiempo de deserealización, en mi caso 53 msg y se cargarán los datos desde el archivo "Strings.txt" en la lista de objetos y se mostrará en la grilla.

Resumen Comparativo

A continuación una figura con un cuadro resumen de tiempos y tamaños por serializador (formato):



Esta resaltado los que mejor rendimiento tienen, es decir el tiempo de Serializado el ganador es el Binario, pero en tamaño (ancho de banda) el ganador es el Strings (Personalizado), además para Servicios Web el Binario no es aplicable por tanto, el mejor Serializador en Performance sería el String.

Sin embrago el comportamiento de los desarrolladores ha sido:
- Web Services XML con SOAP (2002-2007)
- WCF Services con XML (2008-2011)
- Web API con JSON (2012-2015)

Comentario Final

Después de haber tratado detalladamente los Serializadores .NET y analizado su tiempo y tamaño, la recomendación final es que si desean consumir el mínimo ancho de banda, hay que crear su propio serializador (yo le estoy dejando el mio, que poco a poco lo voy a optimizar) ya que es el que mejor rendimiento tiene en velocidad, tamaño e inter-operabilidad.

Claro, muchos dirán que No es Estandar el formato creado, y otros dirán y como hago para consumirlos desde los clientes, es decir como muestro estos datos, así como hay Templates para JSON yo tambien tengo mis propias rutinas que muestran en JavaScript cualquier Strings separados por caracteres, los cuales serán motivos de otros post.

Descarga del Código


El Libro del Día: Pro Asynchronous Programming with .NET

El Libro del Día: 2015-06-04

Titulo: Pro Asynchronous Programming with .NET
Autor: Richard Blewett, Andrew Clymer
Editorial: Apress
Nro Paginas: 336

Capítulos:
Chapter 1: An Introduction to Asynchronous Programming
Chapter 2: The Evolution of the .NET Asynchronous API
Chapter 3: Tasks
Chapter 4: Basic Thread Safety
Chapter 5: Concurrent Data Structures
Chapter 6: Asynchronous UI
Chapter 7: async and await
Chapter 8: Everything a Task
Chapter 9: Server-Side Async
Chapter 10: TPL Dataflow
Chapter 11: Parallel Programming
Chapter 12: Task Scheduling
Chapter 13: Debugging Async with Visual Studio
Chapter 14: Debugging Async - Beyond Visual Studio

Descarga:
Pro_Asynchronous_Programming_with_.NET

miércoles, 3 de junio de 2015

Videos - Tercer Taller .NET Domingos (Parte 1)

Videos del Tercer Taller .NET Domingos (Parte 1)

Comparto con los visitantes del Blog los Videos (sin audio) del Tercer Taller de los Domingos, con temas variados como .NET Remoting, Programación de Tareas, etc.

Nota: El Demo 01 es un Chat en .NET Remoting pero no fue grabado.

Demo 02 - Aplicación con NET Remoting de Login con Captcha

En este video se muestra como crear una aplicación distribuida con .NET Remoting para el CAPTCHA.

Primero se crea la librería remota, luego el servidor remoto que es una aplicación de consola y finalmente una aplicación cliente en Windows Forms.

En la aplicación cliente se llama en forma asíncrona 1000 veces el método remoto que crea el Captcha.


Demo 03 - Aplicación con NET Remoting de Actualización de Archivos

En este video se enseña como crear una aplicación remota con .NET Remoting que permita descargar y actualizar una aplicación desde un servidor a los clientes.

Para esto se crea una aplicación Windows Forms Editor que es la que se va a descargar y actualizar sus versiones. Luego creamos una Librería Remota que devuelva los bytes de la aplicación actualizada.

También creamos una aplicación de Consola que sirve de Servidor Remoto (aloja a la Librería de Actualización) y finalmente la Aplicación Cliente Windows (oculta en el Systray) que permite invocar a la librería remota y actualizar la aplicación.

Finalmente, un problema que se tuvo fue el bloqueo del archivo al usar Reflection para averiguar el Nombre y la Versión del Ensamblado para hacer la actualización, pero este se resolvió no usando la Url sino los bytes del archivo.


Demo 04 - Generador de Código .NET y Performance con Session

En este video muestro un poco sobre mi Generador de Código .NET que crea Procedimientos Almacenados, Entidades de Negocio, Capa de Acceso a Datos, Capa de Reglas del Negocio y Formularios Web Forms de forma eficiente.

También se muestra un proyecto Web de Prueba y se analiza un formulario con una grilla paginada con una tabla de mas de 250,000 registros y como al usar Session el procesador se eleva al 100%.

Se hace un análisis de la performance reduciendo los datos del Procedimiento Almacenado a 100,000 luego a 50000, después a 20,000 y 10,000 observándose que el procesador ya no se eleva.

La conclusión es que cualquier operación de lectura o escritura de un objeto Session con una Lista de Objetos que tiene mas de 20,000 registros ocasiona que el procesador se eleve demasiado, es decir, usar como límite de registros 20,000 para el Session sería lo mas adecuado.


Demo 05 - Copiador de Archivos incluyendo Subdirectorios

En este video enseño como crear una aplicación de consola que permita copiar todos los archivos junto con todos los directorios de una ruta a otra.

Luego se crea una Tarea Programada en Windows usando el Task Scheduler que permita ejecutar dicha aplicación a diario.


Demo 06 - Automatizar Programación de Tareas en .NET (Parte 1)

En este video se muestra la primera parte de una aplicación de Windows Forms que permite Automatizar la Programación de Tareas, es decir, lo que hace el Task Scheduler.

La primera parte consiste en listar todas las tareas programadas en un ListView mostrando el nombre de la tarea, su folder y su estado: en ejecución, detenido, deshabilitado, etc.

Las Tareas que pertenecen al folder DSOFT y las que están en ejecución se muestran con un color de fondo y texto diferente.


Demo 06 - Automatizar Programación de Tareas en .NET (Parte 2)

En este video se muestra la segunda parte de una aplicación de Windows Forms que permite Automatizar la Programación de Tareas, es decir, lo que hace el Task Scheduler.

En esta segunda parte se enseña como crear una nueva tarea, la cual se muestra en la lista de tareas.


Demo 07 - Optimizar Web API con Serializacion de String

Este video sin duda es uno de los mejores, ya que enseño como Optimizar un Servicio Web API usando mi propio Serializador que convierte una Lista de Objetos en cadenas separadas por un caracter los campos y otro los registros.

La técnica tradicional es usar JSON, pero en este video se observa como se reduce a mas de la mitad el tamaño de los bytes enviados desde el servidor web al cliente usando Strings.

En el cliente usamos una función de JavaScript que realiza la presentación de los datos en una tabla.

Además se muestra como hacer para devolver solo las columnas que se desean pintar es decir, sin necesidad de estar creando varias entidades una para cada vista, al serializar indicamos que columnas deseamos enviar, reduciendo mas aún el tamaño del mensaje.

Sin dudas,  un video muy interesante para cualquier desarrollador que quiere optimizar el envío de datos del servidor al cliente, ya que no solo sirve para Web API, sino para cualquier método en MVC o WebForms.


Nota: A partir de mañana voy a publicar varios Demos relacionados a Performance, incluyendo el código de este último Demo de Web API con Serialización Personalizada (mejor que JSON).