miércoles, 14 de abril de 2010

Aprovechando todos los procesadores con Framework 4.0 usando Parallel.For

Como todos saben, ya han publicado el Visual Studio 2010 (para mas información ver: http://www.microsoft.com/spain/visualstudio).
Hace un tiempo salió un artículo en el Blog del equipo de Dynamics acerca de la utilización de la nueva funcionalidad de Framework 4.0 "Parallel.For" para hacer cargas en CRM (http://blogs.msdn.com/crm/archive/2010/03/22/parallelism-using-parallel-for-with-the-crm-sdk.aspx). Si bien esto antes se podía hacer, ahora es mucho mas sencillo.
Ahora que ya tengo instalado el Visual Studio 2010, lo primero que quise hacer es probar esta funcionalidad para intentar ver como afectaría a la hora de hacer cargas.
Bien, lo primero que hice, fue una aplicación de consola, con el siguiente código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Collections;
using ConsoleApplication2.service;

namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Inicio");
CrmAuthenticationToken token = new CrmAuthenticationToken();
token.AuthenticationType = 0;
token.OrganizationName = "DEMO";

CrmService service = new CrmService();
service.Url = "http://192.168.1.99:5555/mscrmservices/2007/crmservice.asmx";
service.CrmAuthenticationTokenValue = token;
service.Credentials = new System.Net.NetworkCredential("administrador","P@ssw0rd","DEMO");

Stopwatch watch = new Stopwatch();
watch.Start();
//Creación de 1000 Cuentas con For
for (int i = 0; i < 1000; i++)
{
account account = new account();
account.name = "Cuenta" + i.ToString();
TargetCreateAccount target = new TargetCreateAccount();
target.Account = account;
CreateRequest create = new CreateRequest();
create.Target = target;
CreateResponse created = (CreateResponse)service.Execute(create);
}
watch.Stop();
Console.WriteLine("Duración total for normal:" + watch.Elapsed.Minutes.ToString() + ":" + watch.Elapsed.Seconds.ToString() + ":" + watch.Elapsed.Milliseconds.ToString());

ParallelOptions ops = new ParallelOptions();
ops.MaxDegreeOfParallelism = 2;
Stopwatch watch2 = new Stopwatch();
watch2.Start();
//Creación de 1000 Cuentas con Parallel.For
Parallel.For(0, 1000, i =>
{
account account = new account();
account.name = "Cuenta" + i.ToString();
TargetCreateAccount target = new TargetCreateAccount();
target.Account = account;
CreateRequest create = new CreateRequest();
create.Target = target;
CreateResponse created = (CreateResponse)service.Execute(create);
});

watch2.Stop();
Console.WriteLine("Duración total ParallelFor:" + watch2.Elapsed.Minutes.ToString() + ":" + watch2.Elapsed.Seconds.ToString() + ":" + watch2.Elapsed.Milliseconds.ToString());

Console.ReadLine();
}
}
}

Como se ven el código, allí simplemente primero creo 1000 cuentas con un "For" normal y luego creo otras 1000 Cuentas con el "Parallell.For" (con hasta 2 procesos simultáneos).
El resultado es el siguiente:

Obviamente el Parallel.For es senciblemente mas rápido a la hora de crear 1000 Cuentas.
El siguiente gráfico compara cuantos segundos son necesarios para la creación de 1000 Cuentas con ambos métodos:


Hay que tener en cuenta que los tiempos también dependerán de cuantos atributos sean necesarios, de las relaciones, de la velocidad del cliente y del servidor, pero yo creo que con esto ya tenemos por lo menos una aproximación del funcionamiento del "Parallel.For".

así que ahora a usarlo!

un saludo

No hay comentarios:

Publicar un comentario