martes, diciembre 09, 2008

3 capas .net

Como empezar estructurar una aplicación 3 capas, vistas la cantidad de lecturas que ha tenido el anterior post sobre aplicaciones 3 capas en .net paso a ampliar susodicho post.

Tipicamente las capas se dividen en Capa de Datos (Data Access), Capa de Lógica o Capa de Reglas de Negocio (Business Rules) y Capa de Presentación (User Interface).Yo incorporaría a estas 3 capas, 1 vertical imprescindible como es la Capa de Entidades (Business Entities) que nos servira para transmitir la información desde la parte inferior a la parte superior.

Hay proyectos que nos pueden facilitar la vida a la hora de confeccionar algunas de las capas, yo recomendaria SQLHelper para la capa de datos, ya que este nos facilita la conexion a bd, la gestion de conexiones y ahorra lineas de código.

Capa de Entidades
Contiene la definición de los objetos que componen el sistema

Capa de Datos
Es la que realiza el guardado físico del objecto, asi como la recuperación del mismo
Las funciones tipicas que ofrece son Insert, Delete, List y Read

Capa de Negocio
Es la que orqueta las diferentes acciones lógicas del negocio, ejemplo, cuando se da de alta un cliente, se envia un email a un usuario.
Las funciones son especificas del negocio y son las usadas desde la interficie, normalmente ofrece las 4 de la capa de datos más alguna específa.

Capa de Presentación
Mediante formularios se va presentando la información y se introduce


Un ejemplo de una aplicación 3 capas verticales + 2 horizontales lo podeis descargar desde el siguiente enlace. Aplicación 3 capas

miércoles, diciembre 03, 2008

Performance .Net: For , Foreach, List.ForEach

Después de leer un artículo de Carlos Walzer sobre performace en asp.net donde este intenta mitificar el mito "Que es más rápido, un dataset, datatable o datareader", tomo la idea prestada y voy a realizar un simil pero con otra sentencia usada a diario, For, Foreach y List.ForEach.

MITO
For, Foreach y List.ForEach:
List.ForEach es el metodo más rápido de iteración, por lo tanto, con un mejor performance , luego el For y por último el Foreach


Para ello creo un proyecto bastante simple donde hare lo mismo con tres códigos diferentes, iterar en un array de integer y ir sumando 1 a una variable en cada iteración.

private void accionFor()

{

for (int j = 0; j <>

{

int resultado=0;

timer.Reset();

timer.Start();

int total = lista.Count;

for (int i = 0; i <>

{

resultado += lista[i];

}

timer.Stop();

if (time1 == 0) time1=timer.ElapsedMilliseconds;

else time1 = (time1 + timer.ElapsedMilliseconds) / 2;

}

}

private void accionForEach()

{

for (int j = 0; j <>

{

int resultado = 0;

timer.Reset();

timer.Start();

lista.ForEach(delegate(int aux)

{

//resultado += aux;

resultado+=aux;

});

timer.Stop();

if (time2 == 0) time2=timer.ElapsedMilliseconds;

else time2 = (time2 + timer.ElapsedMilliseconds) / 2;

}

}

private void accionForIn()

{

for (int j = 0; j <>

{

int resultado = 0;

timer.Reset();

timer.Start();

foreach (int aux in lista)

{

resultado += aux;

}

timer.Stop();

if (time3 == 0) time3=timer.ElapsedMilliseconds;

else time3 = (time3+ timer.ElapsedMilliseconds) / 2;

}

}





Para realizar una medición ajustada tenemos un elemento imprescindible con el que jugar, el número de iteraciones. Y por cada una de los metodos, realizamos una media de 10 ejecuciones, los resultado obtenidos son los siguientes:
Cantidad For List.ForEach Foreach in
4000000 79 55 62
6000000 127 89 96
8000000 163 112 135
10000000 205 138 158
12000000 239 163 190
14000000 283 191 221
16000000 323 217 252
18000000 368 253 323
20000000 410 273 320
22000000 442 305 358

Por lo tanto, confirmamos la primera parte del mito, List.ForEach es la manera de iteración más rápida, el siguiente más rápido es Foreach ... in y por último For.

El hecho que foreach in sea más rápido que for se debe a la falta de optimización del código, ya que en el for, para cada iteración se esta calculando el tamaño del array. A continuación vemos la tabla resultado con esta optimización.

Cantidad For List.ForEach Foreach in
4000000 66 55 91
6000000 94 80 97
8000000 128 116 130
10000000 161 136 177
12000000 214 166 312
14000000 274 218 409
16000000 587 427 310
18000000 368 356 360
20000000 328 290 386
22000000 623 593 390

Ahora quiero probar la diferencia entre la compilación en debug y en release, las anteriores ejecuciones era en debug, ahora pasamos a obtener resultado en release.

Cantidad For List.ForEach Foreach in
4000000 12 26 20
6000000 20 42 28
8000000 26 56 38
10000000 32 66 52
12000000 43 84 57
14000000 49 173 67
16000000 56 112 80
18000000 59 125 93
20000000 65 156 142
22000000 73 162 110

CONCLUSIÓN: En una compilación en Release, las optimizaciones que este efectua en el código permiten mejorar el rendimiento del código en .net (improve performance .net) de manera que el For es más eficiente que el Foreach ... in y este más óptimo que el List.ForEach.


Me gustaria anotar que la medición de tiempos se ha realizado con la clase System.Diagnostics.Stopwatch que de manera muy sencilla te crea un timer para calcular tiempos.