<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Luis Guerrero &#187; Rendimiento</title>
	<atom:link href="http://luisguerrero.net/blog/category/rendimiento/feed/" rel="self" type="application/rss+xml" />
	<link>http://luisguerrero.net</link>
	<description>Hablando de .NET, Silverlight, WPF, Windows Phone 7 y depuración</description>
	<lastBuildDate>Tue, 31 Jan 2012 19:55:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>El recolector de basura</title>
		<link>http://luisguerrero.net/blog/2011/04/05/el-recolector-de-basura/</link>
		<comments>http://luisguerrero.net/blog/2011/04/05/el-recolector-de-basura/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 22:14:16 +0000</pubDate>
		<dc:creator>Guerrerotook</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Programacion]]></category>
		<category><![CDATA[Rendimiento]]></category>
		<category><![CDATA[WinDBG]]></category>
		<category><![CDATA[finalizequeue]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[GCHandle]]></category>
		<category><![CDATA[memory pressure]]></category>
		<category><![CDATA[object]]></category>
		<category><![CDATA[pinned]]></category>
		<category><![CDATA[windbg]]></category>

		<guid isPermaLink="false">http://luisguerrero.net/blog/2011/04/05/el-recolector-de-basura/</guid>
		<description><![CDATA[Todo desarrollador que haya trabajado con .NET, alguna vez ha escuchado hablar del recolector de basura. En este artículo vamos a intentar poner un poco de luz sobre ese concepto, muchas veces misterioso para los programadores. ¿Por qué existe o necesitamos un recolector de basura? El CLR es un maquina virtual en el que se [...]]]></description>
			<content:encoded><![CDATA[<p>Todo desarrollador que haya trabajado con .NET, alguna vez ha escuchado hablar del recolector de basura. En este artículo vamos a intentar poner un poco de luz sobre ese concepto, muchas veces misterioso para los programadores.</p>
<h3>¿Por qué existe o necesitamos un recolector de basura?</h3>
<p>El CLR es un maquina virtual en el que se ejecutan nuestras aplicaciones y .NET es un <i>framework</i>. Microsoft hizo este framework para tener una capa de abastración entre el sistema operativo y las aplicaciones. Una de las cosas más problemáticas en cuanto al desarrollo de aplicaciones es la gestión de memoria. La memoria no es finita y necesita de una gestión, reservar, liberar, compactar, reorganizar. Es por esto que .NET tiene el recolector de basura, para ayudarnos a recolectar los elementos no utilizados y reorganizar la memoria.</p>
<p>Esta caracteristica permite que podamos usar los objetos detro de nuestros lenguajes de programación sin tener en cuenta como se reclican, nostros hacemos el new y el recolector de basura, cuando el objeto ya no sea usado, lo recolectará.</p>
<h3>¿Como se produce esta recolección de basura? y ¿como el GC sabe que objetos no se están usando?.</h3>
<p>Como todos sabreis todos los objetos del framework son referencias a objetos, y cuando nosotros igualamos (a excepción, claro, de que esté sobrecargado el operador ==) lo que estamos haciendo es copiar la referecia en memoria donde está el objeto, es decir copiarmos su dirección y no su contenido. Esto tambien se aplica a los ValueType (structs) solo que el framework trabaja de otra manera, pero eso está fuera de este articulo. </p>
<p>El hecho de que todo sean referencias, hace que cuando nostros tenemos una clase y dentro de esa clase tenemos un campo de un tipo, lo que realmente tenemos es la dirección de memoria donde vive el objeto que referenciamos, lo podemos simplificar en que tenemos un grafo, una serie de elementos representados por vertices y por las aristas que son las referencias entre objetos. </p>
<p>Pues bien cuando nosotros creamos un objeto y lo asignamos lo que estamos haciendo es añadiendo un vertice a nuestro grafo de referencias. Así que una vez que establecemos un objeto a null a menos que tengamos otra referencia (arista) a nuestro elemento ese objeto está completamente aislado del grafo y nadie puede acceder a el.</p>
<p>Pues sabiendo esto, ¿como el GC es capar de saber que un objeto ya no es necesario y puede ser recolectado?, teniendo en cuenta que nadie lo referencia. El secreto está en el heap. El heap mantiene una colección de todos los elementos que el runtime ha creado, es decir, de todos los objetos que tenemos en nuestro grafo pero en formato de lista. Pues bien lo que el GC hace es coger un objecto y saber si hay alguna referncia a ese objeto (una arista) si no es capaz de encontrar una arista hasta ese objeto es porque el objeto nadie lo está referenciado y por eso puede ser recolectado con seguridad. Así se simple. </p>
<p>Ahora bien, el recolector de basura no enumera todos los objetos que estan en el heap y por cada uno de ellos recorre todo el grafo para encontrar una referencia a ese objeto, en vez de eso lo que utiliza son unos objetos raiz, llamados GCRoots, por los cuales empieza el grafo de nuestra aplicación.</p>
<p>Todo esto que he contado como podemos tener evidencias de que es cierto, teniendo un entorno de depuración montado con simbolos y WinDBG + SOS. (Podeis encontrar información de cómo configurar el entorno de depuración en mi blog)</p>
<p>· !dumpheap para mostrar todos los elementos del heap</p>
<p>· !gcroot 0123292 para mostrar cuales son las referencias a un objeto que puede ser:</p>
<p>o En la pila</p>
<p>o En un GCHandle</p>
<p>o En un objeto listo para la finalización</p>
<p>o O en un objeto encontrado el los lugares anteriores</p>
<p>Además de todo eso si sois aventureros y os gusta las experiencias fuertes, podemos visualizar gráficamente el grafo de refencias con sus GCRoots a través una herramienta de profilling que tiene Microsoft, CLRProfiler disponible en <a href="http://www.microsoft.com/downloads">www.microsoft.com/downloads</a></p>
<p align="center"><a href="http://www.luisguerrero.net/Images/41c172a34337_2B1/clip_image002.jpg" target="_blank"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image002" border="0" hspace="12" alt="clip_image002" src="http://www.luisguerrero.net/Images/41c172a34337_2B1/clip_image002_thumb.jpg" width="244" height="148" /></a></p>
<p>Aquí tenemos una captura del grafo de nuestra aplicación de ejemplo, en la que podemos ver el &lt;root&gt; del que os hablaba. </p>
<h3>¿Qué son las generaciones?</h3>
<p>Las generaciones son agrupaciones de las edades de los objetos en memoria. Cuando un objeto se crea está en la generación 0, si se produce una recoleccion de basura lo supervivientes de la generación 0, se les promueve a la generacion 1, y la generación 0 se queda libre y compactada. Se empiezan a crear objetos de nuevo, se lanza otra recoleccion de basura de 0 a 1, los objetos que sobreviven de la generacion 1 pasan a la 2 y los que sobreviven de las generacion 0 pasan a la 1, así sucesivamente.</p>
<p>Solamente existen 3 generaciones, la 0, 1 y 2. Normalmente donde más objeto se generan y se destruyen es en la generación 0 porque es la más usada.</p>
<p>Tamaños:</p>
<p>· Generacion 0: 256 kb (cache segundo nivel del procesador)</p>
<p>· Generacion 1: 2Mb</p>
<p>· Generacion 2: 10Mb</p>
<p>Además de todo eso hay una generación especial para los objetos muy grandes en el framework, LOH (Large object heap), que son los objetos con más de 64kb</p>
<h3>¿Cuándo se lanza una recoleccion de basura?</h3>
<p>Esta es un pregunta complicada porque no tiene una respuesta directa, hay maneras por el cual se puede generar una recolección de basura o por cuales se puede retrasar. Lo más importante a saber es que las recolecciones de basura se hacen cuando la generacion 0 del GC está llena y se va a crear un nuevo objeto, es decir la recoleccion de basura no se produce cuando se llena la memoria, sino cuando se llena la memoria y se intenta crear un objeto. Además de eso hay que tener en cuenta varios factores. El recolector de basura tiene una herustica que le permite tunearse para ofrecer el máximo rendimiento en cada tipo de aplicación, además de que tiene <i>un historial</i> de las acciones que realiza. Por ejemplo, una de las cosas más importantes para el GC es la cantidad de memoria que libera, no la cantidad de objetos que recolecta, si por ejemplo se lanza una recoleccion de memoria y se liberan 150000 objetos que representa 23kb, seguramente el recolector de basura hará que crezca más la memoria de la generacion 0 antes de hacer otra recoleccion, porque lo que le interesa es recolectar mucha memoria no muchas referecias. En ese sentido si el recolector de basura se encuentra con que ha recolectado 150 objetos que ha sido un total de 400kb seguramente la siguiente vez que llene la generación 0 automaticamente generará una nueva recoleccion de basura.</p>
<h3>Porque nunca deberia de llamar a GC.Collect</h3>
<p>Como he explicado antes el recolector de basura tiene su propia heurística que le permite tunearse de manera automática y sin intervención del programador. En las primeras versiones de .NET se podía llamar a la función GC.Collect (que teóricamente fuerza una recolección de basura), pero que en realidad lo que hacía era sugerir una recolección de basura. En ese sentido muchos desarrolladores se quejaron porque en sus aplicaciones llamaban incesantemente al recolector de basura pero no se lanzaba ninguna recolección (lo sabían porque miraban los contadores de rendimiento de .NET), así que Microsoft tuvo que dar marcha atrás e incluir una sobrecarga en la llamada de GC.Collect que aceptaba por parámetro un entero con la generación máxima en la cual se iba a producir la recolección, y los más importante de todo, un enumerado de tipo GCCollectionMode que permitia decir si la recolección era forzada u optimizada.</p>
<p>Como podeis imaginar el modo optimizado es el predeterminado, es decir, el modo en el que le sugieres al recolector de basura que haga su trabajo, pero el modo forzado, como su nombre indica, forzaba a una recolección de basura. Así que si llamamos a esa función así, GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced) estamos obligando a una recolección de basura completa en nuestra aplicación.</p>
<p>Ahora bien porque nunca se debería de llamar a esta función así, porque básicamente si nos encontramos en una situación en donde la memoria de nuestro proceso sube en todos los escenario y el recolector de basura en su modo de funcionamiento normal no es capaz de bajar la memoria de uso del proceso, nos encontramos entonces ante un escenario de pérdida de memoria (leaking) y no en una situación donde el recolector de basura no es capaz de hacer su trabajo. Porque os puedo asegurar que en el 99.99% de las veces en que he visto una aplicación que hacia llamadas al recolector de basura para intentar liberar memoria era porque el proceso en sí tenía problemas de pérdida de memoria, no porque el recolector no fuera capaz por si solo de hacer su trabajo bien.</p>
<h3>Graficas de memoria en forma de montañas</h3>
<p>Llegado a este punto mucha gente se imaginará que la ejecución de las aplicaciones es matemáticamente siempre la misma, es decir, que si en un punto de mi aplicación genero 40mb de memoria y después termino de usar esos objetos automáticamente tengo que ver como mi proceso baja esos 40mb de manera discreta. Pues malas noticias para todos, los sistemas de gestión de memoria sin increíblemente complejos y más para una aplicación de .NET. </p>
<p>Puede que el CLR haya decidido por un casual no liberar esa memoria nativa porque ya que la tiene reservada y no tiene que devolverla al S.O. y más adelante la podrá usar sin tener que volver a pedir memoria a Windows. En ese sentido el CLR también utiliza las funciones de memoria virtual de Windows (VirtualAlloc, VirtualFree, VirtualQuery, VirtualProtect) así que en ese sentido también Windows hace un uso de la memoria de manera conservativa es decir, que no por generar 40mb y ejecutar el recolector de basura automáticamente se liberan 40mb.</p>
<p>Así si por ejemplo el sistema necesita liberar páginas de memoria porque otro proceso, a parte del nuestro en .NET, está haciendo un uso de memoria virtual (no una gran reserva de memoria virtual, acordarse de lo que es una falta de página y como Windows gestiona la memoria de manera perezosa) en ese momento puede decidir recuperar las páginas de memoria de nuestro proceso y entonces nuestra memoria bajará. </p>
<p>Así que simplificar un sistema de gestión de memoria virtual de Windows más el sistema de recolección de basura del CRL de .NET de esa manera es desde mi punto de vista barbaridad. Si queremos saber cuál es el estado de nuestro proceso podemos consultar los contadores de rendimiento para .NET o podemos usar las columnas de Private Bytes, Working Set y Virtual Size en Process Explorer o el comando !address –summary en WinDBG para saber exactamente esa memoria privada en que se gasta en heap, images, ect.</p>
<h3>¿Qué son los objetos pineados en memoria?</h3>
<p>Cuando hablamos de recolección de basura, también hablamos de compactación de la memoria y para que esa compactación de la memoria pueda ocurrir es necesario mover los datos de direcciones de memoria. En un mundo ideal donde las aplicaciones de .NET sean completamente administradas, es decir 100% .NET sin llamadas a Windows esto debería de bastar, pero el caso es que desde .NET podemos hacer llamadas a componentes no administrados que están fuera del paraguas del recolector de basura. </p>
<p>Imaginaros por un momento que estáis haciendo una llamada nativa a una función hecha en C++ que os pide una dirección de memoria donde vive un objeto que él internamente va a utilizar para realizar su trabajo, resulta que como parte de su trabajo ese componente de C++ tiene un temporizador que cada 30sg comprueba una serie de parámetros en ese objeto en contra de un componente de Windows, pero resulta que entre timer y timer, se lanza una recolección de basura y justo el objeto que este componente de C++ utilizaba (porque recordad que le hemos pasado la dirección de memoria, donde vive) es movida por el recolector de basura en una recolección. Justo cuando el siguiente timer se lance y nuestro componente en C++ vaya a leer la memoria se encontrará con que su memoria ahora mismo está ocupada por otro componente. </p>
<p>Este es solo un ejemplo de que a veces no interesa que determinados objetos de .NET estén siempre en la misma dirección de memoria, cualquiera podría haber sugerido que hagamos una copia del objeto y se la pasemos a C++, pero recordad que siempre pasamos referencias y no copias de objetos.</p>
<p>Es por eso en .NET podemos pinear objetos en la memoria, que como su nombre indica, permite que podamos indicarle al recolector de basura que en ningún caso mueva de dirección de memoria este objeto.</p>
<p>A través de una structura llamada GCHandle podemos pinear objetos así: System.Runtime.InteropServices.GCHandle.Alloc(new object,System.Runtime.InteropServices.GCHandleType.Pinned). Esta llamada nos devuelve un objeto de tipo GCHandle en el que podemos consultar el IntPtr del objeto, si esta inicializado y podemos liberarlo.</p>
<h3>Que son las referencias débiles y que es la resurrección de objetos zombies</h3>
<p>Como hemos dicho anteriormente cada vez que hacemos una asignación estamos copiando la referencia en memoria de un objeto, es decir, estamos haciendo una referencia fuerte de un objeto. Si existe una referencia fuerte es porque existe una referencia débil, que siguiendo la analogía tiene que ser una referencia que el recolector de basura no tenga en cuenta para evaluar si un objeto es referenciado por otro. </p>
<p>Para poder usar esas referencias débiles tenemos una clase en .NET llamada WeakReference que como su nombre indica nos permite generar esas referencias débiles. Esta clase tiene varias propiedades interesantes como: IsAlive que nos permite consultar si el objeto al que apuntamos sigue vivo; Target que es una referencia (débil) del objeto y TrackRessurection que nos permite hacer tracking de la resurrección de un objeto.</p>
<p>Pero, ¿Qué es exactamente la resurrección de un objeto?</p>
<p>Cada vez que un objeto es eliminado del grafo de referencias de una aplicación, este pasa a una cola llamada la cola de finalización (comando de WinDBG !finlizaqueue) en la que se le da una última oportunidad de ejecutar el código que tenga en el destructor o en el método Dispose (si implementa IDisposable). En ese instante en el que el objeto está en la cola de finalización un objeto está fuera del grafo de objetos, pero si durante la ejecución de ese código se referencia a si mismo de otro objeto que está en el grafo de objetos de la aplicación a través de un objeto estático, diremos que el objeto ha sufrido una resurrección puesto que el recolector de basura sacará a ese objeto de la cola de finalización y el objeto será de nuevo referenciable y volverá a la vida (metafóricamente hablando).</p>
<h3>¿Por qué el .NET tiene una finalización no determinista?</h3>
<p>Si durante el desarrollo de nuestras clases implementamos IDisposable o creamos un destructor para nuestra clase, el CLR no nos puede asegurar que el destructor de nuestra clase será siempre ejecutado. ¿Por qué?. En ese sentido tenemos que recordar que el CLR es un runtime ejecutado dentro de un proceso y puede que el proceso o el dominio de aplicación se descargue de manera inesperada y en ese sentido el CRL no puede esperar a que todo el código que tengamos en nuestros destructores se ejecute. Por eso se dice que .NET no es determinista en cuanto a la finalización de objetos, porque solamente en el caso de que el dominio de aplicación se descargue o la aplicación se cierre el CLR no nos asegurará que nuestros destructores se ejecuten.</p>
<p>Pero qué pasa si necesito por contrato que el destructor de mi clase se ejecute, o dicho de otra manera, que pasa con las clases que representan recursos del sistema que tienen que ser liberados si o sí.</p>
<p>En este sentido podemos heredad de la clase System.Runtime.ConstrainedExecution.CriticalFinalizerObject haciendo así que el CLR nos asegure que SIEMPRE se ejecutará el destructor de la clase. Como ejemplo diremos que la clase Thread, ReaderWriterLock, SafeHandle y demás heredan de esta clase.</p>
<h3>Conclusiones</h3>
<p>A lo largo de este articulo hemos repasado los básicos de la gestión de memoria por parte del CLR, y hemos visto que es un sistema extraordinariamente complejo para poder simplificarlo de la manera que lo hacen algunos así que en ese sentido paciencia con la memoria y si tenéis algún problema no dudéis con contactar con el equipo DOT (Debugging and Optimization Team) de Plain Concepts que estaremos encantados de buscar problemas de memoria y rendimiento en vuestras aplicaciones.</p>
<p>Luis Guerrero.</p>
]]></content:encoded>
			<wfw:commentRss>http://luisguerrero.net/blog/2011/04/05/el-recolector-de-basura/feed/</wfw:commentRss>
		<slash:comments>3372</slash:comments>
		</item>
		<item>
		<title>TPL – Cancelacion de Task</title>
		<link>http://luisguerrero.net/blog/2009/09/13/tplcancelationtask/</link>
		<comments>http://luisguerrero.net/blog/2009/09/13/tplcancelationtask/#comments</comments>
		<pubDate>Sun, 13 Sep 2009 16:29:10 +0000</pubDate>
		<dc:creator>Guerrerotook</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Rendimiento]]></category>
		<category><![CDATA[TPL]]></category>

		<guid isPermaLink="false">http://www.luisguerrero.net/post.aspx?id=f20cc62a-7260-43a5-ac6c-80877a4c42f6</guid>
		<description><![CDATA[¡Hola a todos! Seguimos con los post sobre Task Parallel Library de .NET Framework 4, en este artículo vamos a ver cuál es el soporte de cancelación de Task que tenemos en TPL. Como hemos comentado en el artículo anterior las Task son la unidad mínima de ejecución de TPL, incluso PLINQ (Parallel LINQ) utiliza [...]]]></description>
			<content:encoded><![CDATA[<p>¡Hola a todos! Seguimos con los post sobre Task Parallel Library de .NET Framework 4, en este artículo vamos a ver cuál es el soporte de cancelación de Task que tenemos en TPL.</p>
<p>Como hemos comentado en el artículo anterior las Task son la unidad mínima de ejecución de TPL, incluso PLINQ (Parallel LINQ) utiliza Task internamente para sus operaciones. También hemos visto como las Task tienen alguna similitud con los Worker Threads del ThreadPool de .NET.</p>
<p>Cuando nosotros en código lanzamos un Worker Thread con el método ThreadPool.QueueWorkItem, estamos encolando un trabajo para que se ejecute en otro Thread diferente, pero no tenemos control en como este Worker thread se ejecuta, de hecho no podemos saber cuándo se ha completado, no podemos cancelarlo y no podemos devolver un resultado de esa ejecución asíncrona. </p>
<p>Esto ahora con las Task cambia, ahora a través de la propiedad Status podemos saber en qué estado está nuestra Task, la propiedad Result nos dará el resultado de la ejecución de la Task. Pero, ¿Qué hay de la cancelación?.</p>
<p>Cancelar un Task no es una tarea trivial, porque implica muchas decisiones y puede conllevar muchos errores. Si pensamos en cómo se cancela un Thread, el CLR lo que hace es inyectar un ThreadAbortException en la ejecución del thread haciendo que este se aborte, pero lo que no podemos controlar es en qué punto de la ejecución del thread se va a producir esto, y lo más peligroso de eso es que podemos estar dentro de un bloque de lock y la inyectarse la excepción puede pasar que nunca se salga de ese bloque de lock, haciendo que pueda pasar un deadlock en nuestro código. Este es solo un ejemplo de lo que puede pasar pero por supuesto puede ser mucho más complicado. </p>
<p>¿Cómo se puede cancelar una Tarea de manera segura? </p>
<p>Hay dos opciones posibles, si la tarea esta creada y se ha llamado al método Start y la Task está esperando para ejecutarse (Status=WaitToRun) y se cancela TPL automáticamente cancelará la tarea por nosotros (Status=Cancelled). Pero si la tarea está ejecutándose o esperando a un evento externo se realiza de otra manera.</p>
<p>Para poder ver esta segunda parte tenemos que comprender primero como se gestiona esto en código para entender cuál es el mecanismo que TPL nos proporciona para cancelar Task.</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">Task t = <span style="color: #0000ff">new</span> Task((index) =&gt;
{
    Thread.SpinWait(1000);
    <span style="color: #0000ff">if</span> (!cancellationSource.IsCancellationRequested)
    {
        Thread.Sleep(r.Next(0, 1000));
    }
}, i, cancellationSource.Token);
list.Add(t);</pre>
</div>
<p>Si nos fijamos en este ejemplo de código al crear una instancia de la clase Task ahora pasamos por parámetro un CancellationToken que nos va a permitir comunicarnos con el sistema de cancelación de TPL. Ese CancellationToken viene de una estructura llamada CancellationTokenSource que es realmente la que gestiona la comunicación de la cancelación de las Task.</p>
<p>Lo primero que hacemos es generar una lista con todas las Task que vamos a ejecutar, con eso lo que tenemos es instancias de la clase Task, pero todavía no se están ejecutando, es después cuando llamamos al método Start de todos los objetos Task a la vez.</p>
<p>Como el TaskScheduler predeterminado es el ThreadPool de .NET al principio en una carga de trabajo tan grande 10000 Task, el ThreadPool se tendrá que tunear a sí mismo para empezar a crear Workers Threads y aumentar dinámicamente la capacidad de ejecución por nosotros. Esta es una de las cosas más cómodas de TPL, porque nosotros no tememos que directamente estar pendiente de la heurística del ThreadPool para saber cuál es el número de Threads ideal para nuestro sistema.</p>
<p>Además de todo esto tenemos un método que nos permite cancelar todas las Task a la vez.</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> CancelTask()
{
    cancellationSource.Cancel();
}</pre>
</div>
<p>Simplemente lo que hacemos es llamar a Cancel del objeto CancellationTokenRequest y este se comunicará con la infraestructura de TPL para empezar la cancelación. Como dijimos antes la cancelación de tareas que están es estado WaitingToRun es automática, pero las que se están ejecutando es más complicado.</p>
<p>Si nos fijamos en el ejemplo de arriba, en el cuerpo del método que se ejecutará por cada Task, hay una sentencia condicional <em>if !cancellationSource.IsCancellationRequested</em> en la que estamos comprobando que no se ha realizado una solicitud de cancelación de tareas. Esto es así porque es la única manera segura y organizada de cancelar un Task. Este ejemplo no es muy representativo para el soporte de cancelación, pero por ejemplo si en esta Task se estuvieran generando por pasos un informe que tarda mucho tiempo, generar el reporte, consulta a la base de datos, ect, podemos hacer comprobaciones en cada paso de que se ha solicitado una cancelación de la Task y así de manera segura cancelar la petición y liberar todos los recursos generados por ese reporte. </p>
<p>Para poder sacar todo el partido de la cancelación en nuestras Task, tenemos que trabajar activamente con TPL para que la experiencia de cancelación sea la más adecuada a cada situación, habrá pasos que no se puedan cancelar hasta un determinado punto, en cualquier caso TPL nunca abortará la ejecución de ese Task por nosotros, pues como he comentado antes esto puede conllevar muchos problemas.</p>
<p><a href="http://www.luisguerrero.net/Images/TPLCancelacindeTask_F507/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.luisguerrero.net/Images/TPLCancelacindeTask_F507/image_thumb.png" width="404" height="346"></a> </p>
<p>Otro de los escenarios posibles cuando se trabaja con cancelación es que de alguna manera nos gustaría saber cuándo un CancellationToken se ha cancelado, para eso tenemos varias opciones, porque el propio CancellationToken tiene un método para que registremos un delegado de tipo Action que será llamado cuando se cancele el CancellationToken. También existe la opción de registrar un objeto de tipo ICancelableOperation, que es la interfaz que implementan el tipo CancellationTokenSource para poder enlazar así objetos de cancelación y crear dependencias entre ellos.</p>
<p>Aquí os podéis descargar el código de ejemplo de la aplicación de WPF.</p>
<p><a href="http://www.luisguerrero.net/downloads/TaskCancel.zip">http://www.luisguerrero.net/downloads/TaskCancel.zip</a></p>
<p>Saludos. Luis.</p>
]]></content:encoded>
			<wfw:commentRss>http://luisguerrero.net/blog/2009/09/13/tplcancelationtask/feed/</wfw:commentRss>
		<slash:comments>3344</slash:comments>
		</item>
		<item>
		<title>TPL – Task</title>
		<link>http://luisguerrero.net/blog/2009/09/07/tpl-task/</link>
		<comments>http://luisguerrero.net/blog/2009/09/07/tpl-task/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 16:37:28 +0000</pubDate>
		<dc:creator>Guerrerotook</dc:creator>
				<category><![CDATA[Rendimiento]]></category>
		<category><![CDATA[TPL]]></category>

		<guid isPermaLink="false">http://www.luisguerrero.net/post.aspx?id=8dd72154-5ab2-445f-9460-ee587b33e40d</guid>
		<description><![CDATA[Como comentamos en el anterior artículo las Task son las unidades básicas de ejecución dentro de TPL (Task Parallel Library) y en este doble artículo vamos a ver cuáles son las posibilidades que tenemos para trabajar con las Task dentro de nuestro código. Una de las misiones de la TPL es ofrece una API consistente [...]]]></description>
			<content:encoded><![CDATA[<p>Como comentamos en el anterior artículo las Task son las unidades básicas de ejecución dentro de TPL (Task Parallel Library) y en este doble artículo vamos a ver cuáles son las posibilidades que tenemos para trabajar con las Task dentro de nuestro código.</p>
<p>Una de las misiones de la TPL es ofrece una API consistente para el trabajo concurrente de software, es decir para tareas que se van a ejecutar de manera concurrente en un sistema con más de un procesador. Como bien es sabido la unidad mínima que el SO es cada de enviar para ejecutar es un Thread, pero nosotros aquí estamos hablando de Task. ¿Qué relación hay entre un Thread y un Task?. </p>
<p>Un thread es una unidad mínima y demasiado concreta para ejecutar código de manera concurrente. Dentro de .NET se puede crear una instancia de la clase Thread para ejecutar un método que nosotros queramos dentro de un thread diferente, pero una vez que ese método se ejecuta el Thread termina y se liberan los recursos utilizados por él. Es por eso que utilizar una estructura un poco más de alto nivel nos ayuda a abstraernos de cómo nuestras Task se ejecutan.</p>
<p>Ahora bien esto no quiere decir que las Task *no* se e ejecutan dentro de un thread, sino que también se ha creado una estructura intermedia llamada TaskScheduler que nos permite definir cómo se van a ejecutar nuestras Task. La igualdad con respecto al par Schedule/Thread es muy parecida pues tenemos conceptos muy similares, pero como veremos más adelante las Task son mucho más flexibles que un Thread y permite un sinfín de configuraciones, es más permiten que se ejecuten de manera síncrona, cosa que un thread no puede.</p>
<h3>Basic - Creación de una Task.</h3>
<p>Para crear una instancia de la clase Task podemos hacerla de varias maneras, aquí tenemos algunos ejemplos. </p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">Task t = <span style="color: #0000ff">new</span> Task(() =&gt;
{
    Console.WriteLine(<span style="color: #006080">"hola desde un task"</span>);
    Thread.Sleep(1000 * 4);
});

Task argumento = <span style="color: #0000ff">new</span> Task(index =&gt;
{
    <span style="color: #0000ff">int</span> <span style="color: #0000ff">value</span> = (<span style="color: #0000ff">int</span>)index;
    <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i = 0; i &lt; <span style="color: #0000ff">value</span>; i++)
    {
        DoStuff();
    }
    Thread.Sleep(1000 * 4);
}, 90);</pre>
</div>
<p>En ambos ejemplo se han utilizado Lambdas para crear los delegados que ejecutarán el código pero se puede utilizar el delegado Action y Action&lt;T&gt; para sacar ese valor a un método externo.</p>
<p>Con esto simplemente lo que hemos hecho es definir únicamente el objeto Task y ahora mismo esta simplemente creado pero no se le ha especificado que se tiene que ejecutar. Para ejecutarlo tenemos dos opciones, de manera síncrona y de manera asíncrona (concurrente). Puede parecer algo raro el tener el soporte de ejecución síncrona el algo que está pensado para ejecutarse de manera concurrente siempre, pero es que en algunos casos es útil y así podemos definir todo nuestro trabajo con Task y luego decidir cómo queremos ejecutar.</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">t.RunSynchronously();            

t.Start();    </pre>
</div>
<p>En el método Start tenemos una sobrecarga que nos permite especificar cuál es el TaskScheduler en el que queremos ejecutar nuestra Task. Si no especificamos ninguno el sistema automáticamente utiliza un TaskScheduler que utiliza internamente el ThreadPool de Windows para ejecutar el código. Por supuesto podemos definir y crear nuestros propios TaskScheduler simplemente heredando de la clase TaskScheduler. Además del que está definido con el ThreadPool si estamos dentro de una aplicación de UI como Windows Forms o WPF estos disponen de un TaskScheduler propio para ejecutar tareas dentro del bucle de mensajes de la aplicación.</p>
<p>Para poder acceder a este TaskScheduler tenemos que llamar a este código:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">TaskScheduler ui = TaskScheduler.FromCurrentSynchronizationContext();</pre>
</div>
<p>Además de estas opciones tenemos algunas otras con las que podemos trabajar con Task. Podemos esperar la ejecución de una Task concreta un tiempo determinado o simplemente podemos esperar infinitamente hasta que la tarea termine. </p>
<p>Una de las sobrecargas del método wait acepta un objeto de tipo CancellationToken que como su nombre indica es un objeto que nos ayuda a tener un soporte de cancelación de Task que veremos más adelante.</p>
<p>También disponemos de varias propiedades dentro de la clase Task que nos dan información del estado de la tarea como:</p>
<ul>
<li><strong>State</strong>: enumerado que nos indica en qué estado está la Task, como: Created, WaitToRun, Running, RanToCompletion, ect. </li>
<li><strong>AsynState</strong>: objeto de usuario. </li>
<li><strong>Exception</strong>: si se ha producido una excepción durante la ejecución de la Task y no se ha controlado el estado de la Task será Faulted y en esta propiedad aparecerá un objeto de tipo AggregateException que contiene una lista de todas las excepciones que se han producido durante la ejecución de la Task. </li>
<li><strong>Result</strong>: obtiene de manera segura el resultado de la ejecución de la Task. </li>
</ul>
<p>Como última opción veremos que tenemos un método llamado ContinueWith que nos permite ejecutar la Task especificada justo después de que esta termine pudiendo así enlazar Task y crear dependencias entre ellas. Esto es muy útil cuando se trabaja con funciones que van a tardar mucho en ejecutarse como una lectura de un fichero, una query en una base de datos o una actividad en background.</p>
<p>Con lo que dijimos antes vamos a ver un ejemplo utilizando TaskScheduler.FromCurrentSynchronizationContext() en una aplicación WPF para ver ContinuwWith.</p>
<p>Como bien es sabido en WPF y en Windows Forms no es posible actualizar el estado de un objeto de UI desde el Thread que no es el Thread que creo el objeto, es decir si estamos ejecutando código desde otro Thread, algo normal con las Task, no vamos a poder actualizar el resultado de nuestra Task, así que tenemos que sincronizar el acceso. </p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">Task.Factory.StartNew(() =&gt;
{
    <span style="color: #008000">// simulando una operacion lenta</span>

    Thread.Sleep(1000 * 2);
    <span style="color: #0000ff">return</span> <span style="color: #006080">"hola"</span>;

}).ContinueWith(task =&gt;
{
    result.Text = task.Result;

}, TaskScheduler.FromCurrentSynchronizationContext());</pre>
</div>
<p>Aquí está el disponible el código de ejemplo.</p>
<p><a href="http://www.luisguerrero.net/downloads/task101.zip">http://www.luisguerrero.net/downloads/task101.zip</a></p>
<p>&nbsp;</p>
<p>Saludos. Luis.</p>
]]></content:encoded>
			<wfw:commentRss>http://luisguerrero.net/blog/2009/09/07/tpl-task/feed/</wfw:commentRss>
		<slash:comments>3079</slash:comments>
		</item>
		<item>
		<title>Task Parallel Library &#8211; Introduccion</title>
		<link>http://luisguerrero.net/blog/2009/09/06/task-parallel-library-introduccion/</link>
		<comments>http://luisguerrero.net/blog/2009/09/06/task-parallel-library-introduccion/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 15:31:24 +0000</pubDate>
		<dc:creator>Guerrerotook</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Rendimiento]]></category>
		<category><![CDATA[TPL]]></category>

		<guid isPermaLink="false">http://www.luisguerrero.net/post.aspx?id=0c34499c-9439-416e-97b7-c356545bedc9</guid>
		<description><![CDATA[Una de las nuevas novedades que .NET Framework 4.0 incluye es el la Task Parallel Library una serie de APIS nuevas para la programación multihilo. La idea principal de esta librería, que viene incluida en el propio framework, es que cuando tengamos que añadir paralelismo y concurrencia a nuestras aplicaciones sea de lo más sencillo. [...]]]></description>
			<content:encoded><![CDATA[<p>Una de las nuevas novedades que .NET Framework 4.0 incluye es el la Task Parallel Library una serie de APIS nuevas para la programación multihilo. La idea principal de esta librería, que viene incluida en el propio framework, es que cuando tengamos que añadir paralelismo y concurrencia a nuestras aplicaciones sea de lo más sencillo. </p>
<p>Actualmente los procesadores ya no incrementan la velocidad en Gigahercios sino que lo que hacen es replicar el hardware haciendo que nos encontremos dentro del mismo encapsulado FPGA dos procesadores exactamente iguales con sus caches de segundo y primer nivel. Esto cambia la manera de desarrollar software porque ya no nos encontramos con procesadores más rápidos sino con procesadores con más cores, 2,4,6,8 ect. </p>
<p>Con este nuevo escenario tenemos los desarrolladores tenemos que empezar a paralelizar nuestro software para explotar toda la potencia de los procesadores. </p>
<p>Una de las cosas buenas de la TPL, es que si la maquina donde se va a ejecutar tiene 2, 4 o 8 procesadores, la TPL es capaz de escalar sin necesidad de recompilar ni configurar, es decir es capaz de usar todos los cores disponibles. </p>
<p>Eso quiere decir que cuanto más cores utilicemos más velocidad ganaremos, aunque esto no es siempre así, porque no todas las tareas son sensibles de ser paralelizadas. Además hay que tener en cuenta que usar la TPL añade complejidad en la ejecución de la aplicación y esto en algunas ocasiones puede hacer que se degrade el rendimiento y no lo aumente. Hablaremos de eso más adelante.</p>
<p>Aquí tenemos la primera toma de contacto con la TPL:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">Parallel.For(startIndex, endIndex, (currentIndex) =&gt; DoSomeWork(currentIndex));</pre>
</div>
<p>Parallel.For nos permite ejecutar de manera concurrente el cuerpo de un bucle for, haciendo que la ejecución se propague por todos los cores disponibles en el sistema. Así de sencillo.</p>
<p>Pero como hemos comentado antes no esto a veces aumenta el rendimiento y en otros lo degrada. Veamos porque.</p>
<p>Cuando realizamos un bucle normal todo el código se ejecuta de manera secuencial, es decir una instrucción detrás de otra, pero cuando estamos realizando una paralelizacion de nuestro código tenemos varios threads que están ejecutando código en el mismo instante de tiempo. Si nos ponemos a pensar cómo se podría implementar a mano un Parallel.For, lo primero que tendríamos que hacer es realizar una partición de las iteraciones para dependiendo de los procesadores que tengamos repartir el trabajo.</p>
<p>Si tenemos por ejemplo que recorrer una lista de 50000 elementos y tenemos 2 procesadores, podemos partir la lista de dos sublistas de 25000 y generar dos threas que se encarguen de recorrer esos elementos. Ponemos los threads a ejecutar y tenemos que <i>sincronizar</i> cuando los dos threads terminan.</p>
<p>Básicamente esto es de lo que se encarga el Parallel.For de hacer por nosotros, de una manera cómoda y elegante.</p>
<p>Ahora bien, ¿Cuándo no es recomendable realizar un Parallel.For?, hay una regla que funciona en la mayoría de los casos, cuando el tiempo de ejecución del cuerpo del for sea mayor o igual que el tiempo de creación de los threas y de la sincronización, también es lo mismo si tenemos colecciones pequeñas. ¿Qué quieres decir esto?, veamos un ejemplo:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #0000ff">using</span> System;
<span style="color: #0000ff">using</span> System.Collections.Generic;
<span style="color: #0000ff">using</span> System.Linq;
<span style="color: #0000ff">using</span> System.Text;
<span style="color: #0000ff">using</span> System.Threading.Tasks;
<span style="color: #0000ff">using</span> System.Diagnostics;

<span style="color: #0000ff">namespace</span> ParalleFor
{
    <span style="color: #0000ff">class</span> Program
    {
        <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> Main(<span style="color: #0000ff">string</span>[] args)
        {
            <span style="color: #0000ff">new</span> Program();
        }

        <span style="color: #0000ff">private</span> List&lt;<span style="color: #0000ff">int</span>&gt; GetRandomList()
        {
            List&lt;<span style="color: #0000ff">int</span>&gt; list = <span style="color: #0000ff">new</span> List&lt;<span style="color: #0000ff">int</span>&gt;();
            <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i = 0; i &lt; 90000000; i++)
            {
                list.Add(i);
            }
            <span style="color: #0000ff">return</span> list;
        }

        <span style="color: #0000ff">public</span> Program()
        {
            List&lt;<span style="color: #0000ff">int</span>&gt; list = GetRandomList();

            Stopwatch st = <span style="color: #0000ff">new</span> Stopwatch();

            <span style="color: #008000">// sum all</span>
            <span style="color: #0000ff">decimal</span> <span style="color: #0000ff">value</span> = 2;
            st.Start();
            <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i = 0; i &lt; list.Count; i++)
            {
                <span style="color: #0000ff">decimal</span> final = <span style="color: #0000ff">value</span> * list[i];
            }
            st.Stop();
            Console.WriteLine(st.Elapsed);
            st.Reset();

            st.Start();
            Parallel.For(0, list.Count, index =&gt;
            {
                <span style="color: #0000ff">decimal</span> final = <span style="color: #0000ff">value</span> * list[(<span style="color: #0000ff">int</span>)index];
            });
            st.Stop();
            Console.WriteLine(st.Elapsed);
        }
    }
}</pre>
</div>
<p>Si nos fijamos la lista de con la que trabajamos es realmente grande, eso significa que si paralelizamos el bucle for ganaremos en rendimiento como muestra la salida de la ejecución. Pero si tenemos una lista pequeña no ganaremos tiempo sino que perderemos porque tenemos que sincronizar los n threas para esperar a que todos terminen, además del tiempo necesario para inicializarlos. </p>
<p>Otro de los grandes problemas de la paralelizacion es que necesitamos estructuras para sincronizar nuestro código y tener claro los conceptos de: locks, deadlocks, race condition (data and flow), etc. </p>
<p>En el siguiente artículo veremos el soporte para Task, las unidades básicas de ejecución dentro de TPL. </p>
</p>
<p>Aquí tenéis el código fuente del ejemplo. </p>
<p><a href="http://www.luisguerrero.net/downloads/parallefor.zip">http://www.luisguerrero.net/downloads/parallefor.zip</a></p>
<p>&nbsp;</p>
<p>Saludos. Luis.</p>
]]></content:encoded>
			<wfw:commentRss>http://luisguerrero.net/blog/2009/09/06/task-parallel-library-introduccion/feed/</wfw:commentRss>
		<slash:comments>3950</slash:comments>
		</item>
		<item>
		<title>Firefox 3.5 : Multithreading javascript code</title>
		<link>http://luisguerrero.net/blog/2009/07/01/firefox-3-5-multithreading-javascript-code/</link>
		<comments>http://luisguerrero.net/blog/2009/07/01/firefox-3-5-multithreading-javascript-code/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 15:06:50 +0000</pubDate>
		<dc:creator>Guerrerotook</dc:creator>
				<category><![CDATA[Rendimiento]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.luisguerrero.net/post.aspx?id=d190aefb-cbef-456d-97d6-70a808e1e478</guid>
		<description><![CDATA[Ya ha salido Firefox 3.5… pero yo solamente voy a hablar de una característica que han introducido la gente de Mozilla que es realmente interesante: Web Workers Threads La utilización de java script en los navegadores se ha disparado, todo se hace hoy en día con javascript y eso ha tenido como consecuencia que la [...]]]></description>
			<content:encoded><![CDATA[<p>Ya ha salido Firefox 3.5… pero yo solamente voy a hablar de una característica que han introducido la gente de Mozilla que es realmente interesante: Web Workers Threads</p>
<p>La utilización de java script en los navegadores se ha disparado, todo se hace hoy en día con javascript y eso ha tenido como consecuencia que la gente que se dedica a hacer los navegadores mejore cada día la velocidad con la que se ejecute el código. Pero aunque tenemos muchos tipos de runtimes para ejecutar javascript V8, TraceMonkey, IE todos tienen una peculiaridad y es que se ejecuta el código síncronamente, no permitiendo que se paralelice la ejecución de código.</p>
<p>Pero ese día ha acabado, la gente de Firefox consciente de que se necesita incrementar la velocidad de javascript ha decidido incluir esta característica en Firefox 3.5.</p>
<p>La idea es simple:</p>
<div>
<pre><span style="color: #0000ff">var</span> myWorker = <span style="color: #0000ff">new</span> Worker(<span style="color: #006080">'my_worker.js'</span>);
myWorker.onmessage = <span style="color: #0000ff">function</span>(<span style="color: #0000ff">event</span>) {
  print(<span style="color: #006080">&quot;Called back by the worker!\n&quot;</span>);
};</pre>
</div>
<p>Aquí podemos ver un ejemplo de código para generar ese worker thread, que podemos encontrar en la wiki de desarrollo de Firefox <a href="https://developer.mozilla.org/En/Using_DOM_workers">https://developer.mozilla.org/En/Using_DOM_workers</a></p>
<p>A mí personalmente no me gusta nada Javascript ni html, es todo muy tedioso y uno tiene que aprender a hacer muchos hacks para hacer cualquier cosa incluso para centrar una imagen en la pantalla, pero claro es mi opinión.</p>
<p>Luis.</p>
<blockquote></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://luisguerrero.net/blog/2009/07/01/firefox-3-5-multithreading-javascript-code/feed/</wfw:commentRss>
		<slash:comments>2798</slash:comments>
		</item>
		<item>
		<title>Tool: Memory Pressure</title>
		<link>http://luisguerrero.net/blog/2009/06/23/tool-memory-pressure/</link>
		<comments>http://luisguerrero.net/blog/2009/06/23/tool-memory-pressure/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 19:40:00 +0000</pubDate>
		<dc:creator>Guerrerotook</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Rendimiento]]></category>

		<guid isPermaLink="false">http://www.luisguerrero.net/post.aspx?id=e304c854-93ce-4118-b55f-31187a4385eb</guid>
		<description><![CDATA[Esta sencilla herramienta permite generar presi&#243;n en la memoria del sistema a nuestro gusto. La interfaz de usuario es muy sencilla, podemos seleccionar la cantidad de Megabytes que queremos reservar y cu&#225;l es el tama&#241;o de los bloques que queremos usar. Hay que tener en cuenta que esta aplicaci&#243;n utiliza la reserva de memoria del [...]]]></description>
			<content:encoded><![CDATA[<p>
Esta sencilla herramienta permite generar presi&oacute;n en la memoria del sistema a nuestro gusto.
</p>
<p>
<a href="http://www.luisguerrero.net/Images/ToolMemoryPressure_1221A/clip_image002.jpg"><img style="float: none;margin-left: auto;margin-right: auto;border-width: 0px" src="/Images/ToolMemoryPressure_1221A/clip_image002_thumb.jpg" border="0" alt="clip_image002" width="404" height="296" /></a>
</p>
<p>
La interfaz de usuario es muy sencilla, podemos seleccionar la cantidad de Megabytes que queremos reservar y cu&aacute;l es el tama&ntilde;o de los bloques que queremos usar. Hay que tener en cuenta que esta aplicaci&oacute;n utiliza la reserva de memoria del heap de Windows, es decir llama a <a href="http://msdn.microsoft.com/en-us/library/5cyb68cy.aspx" target="_blank" title="Marshal.AllocHGlobal">Marshal.AllocHGlobal</a> que a su vez llama a <a href="http://msdn.microsoft.com/en-us/library/aa366723.aspx" target="_blank" title="LocalAlloc">LocalAlloc</a>.
</p>
<p>
Una vez que tenemos la memoria reservada podemos liberarla para poder eliminar la presi&oacute;n.
</p>
<p>
Durante la reserva de memoria se llama a <a href="http://msdn.microsoft.com/en-us/library/system.gc.addmemorypressure.aspx" target="_blank" title="GC.AddMemoryPressure">GC.AddMemoryPressure</a> que notifica al recolector de basura la presi&oacute;n actual que se est&aacute; haciendo en memoria nativa.
</p>
<p align="left">
Os podeis instalar este software desde: <a href="http://www.luisguerrero.net/applications/MemoryPressure/">http://www.luisguerrero.net/applications/MemoryPressure/</a>
</p>
<p align="left">
Tambien os podeis descargar el c&oacute;digo fuente: <a href="http://www.luisguerrero.net/downloads/MemoryPressure.zip">http://www.luisguerrero.net/downloads/MemoryPressure.zip</a>
</p>
<p>
Luis.</p>
]]></content:encoded>
			<wfw:commentRss>http://luisguerrero.net/blog/2009/06/23/tool-memory-pressure/feed/</wfw:commentRss>
		<slash:comments>2687</slash:comments>
		</item>
		<item>
		<title>Rendimiento para el modelado de clases</title>
		<link>http://luisguerrero.net/blog/2009/06/01/rendimiento-para-el-modelado-de-clases/</link>
		<comments>http://luisguerrero.net/blog/2009/06/01/rendimiento-para-el-modelado-de-clases/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 23:22:54 +0000</pubDate>
		<dc:creator>Guerrerotook</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Rendimiento]]></category>

		<guid isPermaLink="false">http://www.luisguerrero.net/post.aspx?id=68047561-00b4-4f37-b1a4-478a375ac133</guid>
		<description><![CDATA[Rendimiento. En muchos proyectos en los que trabajo una de las preocupaciones a la hora de hacer el proyecto es el rendimiento de la aplicación Una de las tareas, por no decir la única, es trabajar con datos en una aplicación, modelamos constantemente clases que tiene estado y a su vez exponen una serie de [...]]]></description>
			<content:encoded><![CDATA[<p>Rendimiento. En muchos proyectos en los que trabajo una de las preocupaciones a la hora de hacer el proyecto es el rendimiento de la aplicación</p>
<p>Una de las tareas, por no decir la única, es trabajar con datos en una aplicación, modelamos constantemente clases que tiene estado y a su vez exponen una serie de métodos para que los podamos invocar. Hoy a lo que me voy a dedicar a explicar es justamente a ese modelado de datos, al estado de nuestras clases.</p>
<p>Dentro de .NET Framework tenemos varias maneras de definir el estado de una clase:</p>
<ul>
<li>Field (Campo) </li>
<li>Property (Propiedad) </li>
<li>DependencyProperty (Propiedades de Dependencia) </li>
</ul>
<p>Estas últimas están pensadas para la interacción de esas clases con Interfaz de Usuario (UI).</p>
<p>Las propiedades son una normalización de los métodos de acceso (set) o de obtención (get) que normalmente se hacía para obtener el acceso a los campos o modificarlos. Realmente las variables se guardan en los campos (field) solo que las propiedades permiten normalizar el acceso y encapsular su funcionalidad de acceso. Son implementadas como métodos dentro del ensamblado.</p>
<p>Lo que vamos a ver en este post es cual la velocidad de acceso a estas propiedades desde .net para saber cuál es la mejor opción si estamos trabajando con el estado de las propiedades y campos. Cualquiera me podría decir que según la lista anterior está claro que siempre la mejor opción (desde el punto de vista del rendimiento) son los campos (Field) puesto que accederos directamente y sin intermediarios, pero además de eso cuando los proyectos empiezan a complicarse puede pensar en usar la reflexión para acceder a los datos, porque se quiere automatizar el acceso a las propiedades de las clases.</p>
<p>Así que lo que vamos a hacer es tener dos tipos de clases una con campos y propiedades, (Field y Property), otra con DependencyProperty y vamos a medir el tiempo que tardamos en acceder a esas variables. Una de las desventajas de usar DP es que para poder usar su funcionalidad tenemos que heredar de la clase DependencyObject, que es la clase que implementa la funcionalidad de DP. Además como he comentado anteriormente las DP únicamente se usar para definir las propiedades de los controles de interfaz de usuario y de los objetos de negocio que interactúan con la UI.</p>
<p>Lo que vamos a hacer son una serie de pruebas con una clase intermedia para medir el tiempo y que se encargue de ejecutar el bloque de código n veces y de medir el tiempo que tarda en hacerlo.</p>
<p>Para la medida del tiempo no vamos a usar DateTime.Now antes de empezar y después de ejecutar porque la medida de tiempo de DateTime.Now no es de alta resolución y no vamos a tener la precisión que necesitamos para medir diferencias de tiempo. En vez de DateTime.Now vamos a usar Stopwatch, clase que está en System.Diagnosis que nos permite hacer medidas de tiempo en alta resolución, el uso de esta clase es bastante sencilla así que el lector la podrá descubrir por el mismo.</p>
<p>Vamos al lio, tenemos está clase normal de C#</p>
<div>
<pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> NormalType
{
    <span style="color: #0000ff">internal</span> <span style="color: #0000ff">int</span> number;

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> Number
    {
        get { <span style="color: #0000ff">return</span> number; }
        set { number = <span style="color: #0000ff">value</span>; }
    }

    <span style="color: #0000ff">internal</span> <span style="color: #0000ff">string</span> _string;

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> String
    {
        get { <span style="color: #0000ff">return</span> _string; }
        set { _string = <span style="color: #0000ff">value</span>; }
    }
    <span style="color: #0000ff">internal</span> Item item;

    <span style="color: #0000ff">public</span> Item Item
    {
        get { <span style="color: #0000ff">return</span> item; }
        set { item = <span style="color: #0000ff">value</span>; }
    }
}</pre>
</div>
<p>Como podéis ver es una clase con tres propiedades un entero, un string y un tipo referencia complejo (Item), todas las propiedades tienen un campo que respalda el valor, así que realmente las propiedades simplemente exponen los valores de los campos sin más.</p>
<div>
<pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> DependencyPropertyType : DependencyObject
{
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> Number
    {
        get { <span style="color: #0000ff">return</span> (<span style="color: #0000ff">int</span>)GetValue(NumberProperty); }
        set { SetValue(NumberProperty, <span style="color: #0000ff">value</span>); }
    }

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">readonly</span> DependencyProperty NumberProperty =
        DependencyProperty.Register(<span style="color: #006080">&quot;Number&quot;</span>, <span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">int</span>), <span style="color: #0000ff">typeof</span>(DependencyPropertyType), <span style="color: #0000ff">new</span> PropertyMetadata(0));

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> String
    {
        get { <span style="color: #0000ff">return</span> (<span style="color: #0000ff">string</span>)GetValue(StringProperty); }
        set { SetValue(StringProperty, <span style="color: #0000ff">value</span>); }
    }

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">readonly</span> DependencyProperty StringProperty =
        DependencyProperty.Register(<span style="color: #006080">&quot;String&quot;</span>, <span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">string</span>), <span style="color: #0000ff">typeof</span>(DependencyPropertyType), <span style="color: #0000ff">new</span> PropertyMetadata(<span style="color: #0000ff">null</span>));

    <span style="color: #0000ff">public</span> Item Item
    {
        get { <span style="color: #0000ff">return</span> (Item)GetValue(ItemProperty); }
        set { SetValue(ItemProperty, <span style="color: #0000ff">value</span>); }
    }

    <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">readonly</span> DependencyProperty ItemProperty =
        DependencyProperty.Register(<span style="color: #006080">&quot;Item&quot;</span>, <span style="color: #0000ff">typeof</span>(Item), <span style="color: #0000ff">typeof</span>(DependencyPropertyType), <span style="color: #0000ff">new</span> PropertyMetadata(<span style="color: #0000ff">null</span>));

}</pre>
</div>
<p>Esta otra clase es la clase que implementa las DependencyProperty, como veis ahora por cada propiedad hay una definición de una clase de tipo DependencyProperty que es estático y de solo lectura (static readonly) y además no es el tipo que definimos las propiedades. Eso que significa que los valores de esta clase son compartidos, desde luego no porque las propiedades son de instancia no estáticas, solo que ahora utilizamos dos métodos helpers que nos ayudan a acceder y establecer los valores de las propiedades (GetValue,SetValue). Esos dos métodos están definidos en la clase base DependencyObject. Realmente nosotros no tenemos información de donde se están guardando esas variables dentro de nuestra clase no hay ningún campo (Field) ni lista ni nada que nos indique donde se están almacenando esos valores, y si miramos en la clase base nos pasa lo mismo. En otro post desvelare toda la potencia y misterios de las DP ahora simplemente lo usaremos sin más para esta prueba de rendimiento.</p>
<p>Ahora lo que vamos a hacer son las pruebas en sí de acceso a estos valores.</p>
<p><a href="http://www.luisguerrero.net/Images/Rendimientoparaelmodeladodeclases_2B7/image.png"><img style="border-bottom: 0px;border-left: 0px;border-top: 0px;border-right: 0px" border="0" alt="image" src="http://www.luisguerrero.net/Images/Rendimientoparaelmodeladodeclases_2B7/image_thumb.png" width="500" height="327" /></a>&#160; </p>
<p><table border="0" cellspacing="0" cellpadding="0" width="100%">
<tbody>
<tr>
<td valign="bottom"><strong></strong></td>
<td valign="bottom">
<p><strong>Sin reflexion</strong></p>
</td>
<td valign="bottom">
<p><strong>Con Reflexion</strong></p>
</td>
</tr>
<tr>
<td valign="bottom">
<p><strong>Getter Field</strong></p>
</td>
<td valign="bottom">
<p>92,176</p>
</td>
<td valign="bottom">
<p>4483,588</p>
</td>
</tr>
<tr>
<td valign="bottom">
<p><strong>Getter Property</strong></p>
</td>
<td valign="bottom">
<p>142,813</p>
</td>
<td valign="bottom">
<p>3169,277</p>
</td>
</tr>
<tr>
<td valign="bottom">
<p><strong>Getter Dependency Property</strong></p>
</td>
<td valign="bottom">
<p>755,433</p>
</td>
<td valign="bottom">
<p>1619,854</p>
</td>
</tr>
<tr>
<td valign="bottom">
<p><strong>Setter Field</strong></p>
</td>
<td valign="bottom">
<p>0,607</p>
</td>
<td valign="bottom">
<p>3716,121</p>
</td>
</tr>
<tr>
<td valign="bottom">
<p><strong>Setter Property</strong></p>
</td>
<td valign="bottom">
<p>0,584</p>
</td>
<td valign="bottom">
<p>2600,364</p>
</td>
</tr>
<tr>
<td valign="bottom">
<p><strong>Setter Dependency Property</strong></p>
</td>
<td valign="bottom">
<p>129,623</p>
</td>
<td valign="bottom">
<p>973,799</p>
</td>
</tr>
</tbody>
</table>
<p>La prueba está dividida en dos grandes grupos Setters y Getters (establecer y obtener).</p>
<p>Para los Setters (establecer) los campos tiene el mejor rendimiento cuando se trabaja con ellos, pero son los que tiene el peor rendimiento cuando se trata de acceder a través de reflexión, las propiedades es el mismo caso solo que se mejora un poco el tiempo de acceso desde reflexión y para las Dependency Property están muy equilibradas en cuanto a tiempo de acceso con y sin reflexión.</p>
<p>En el caso de Getters (obtener) la historia se repite, los campos y propiedades son increíblemente rápidos, pero cuando se trabaja con ellos a través de reflexión se penaliza, las Dependency Property en relación con el Setter son más rápidas con y sin reflexión.</p>
<p>El caso especial de las Dependency Proeprty.</p>
<p>¿Por qué las Dependency Properties tiene mejores tiempos?, podríamos decir que la prueba esta adulterada, porque realmente siempre se utiliza los métodos GetValue y SetValue que DependencyObject nos proporciona para acceder a esos valores y ahí es donde está la sobrecarga pero hay que tener en cuenta que la reflexión usada en esta prueba es solo para acceder a las instancias de las DependencyProperty que son necesarias en las llamadas de GetValue y SetValue.</p>
<p>Por si sentís curiosidad los valores de las instancias de clases que heredan de DependencyObject se guardan en un campo interno de la clase DependencyObject llamado _effectiveValues de tipo EffectiveValueEntry,</p>
<p>private EffectiveValueEntry[] _effectiveValues;</p>
<p>EffectiveValueEntry es la clase que manera el valor de una Dependency Property, cada una de estos EffectiveValueEntry tiene asociado un índice dentro de todos los registros de Dependency Proeprty al cual nosotros podemos acceder desde DependencyProperty.GlobalIndex (int) pero no podemos usar de ninguna manera, no sé porque Microsoft ha permitido acceder a esta propiedad si no tiene utilizad.</p>
<p>La solución de Visual Studio para que hagáis vuestras pruebas.</p>
<p><a href="http://www.luisguerrero.net/downloads/DPPerformance.zip">http://www.luisguerrero.net/downloads/DPPerformance.zip</a> </p>
<p>Luis Guerrero.</p>
]]></content:encoded>
			<wfw:commentRss>http://luisguerrero.net/blog/2009/06/01/rendimiento-para-el-modelado-de-clases/feed/</wfw:commentRss>
		<slash:comments>3820</slash:comments>
		</item>
	</channel>
</rss>

