2011-03-04 16 views
6

Resumen: He cambiado de estructura System.Threading.Tasks.Parallel.ForEach y concurrente de datos a un PLINQ sencilla consulta (LINQ paralelo). La velocidad fue increíble.PLINQ inherentemente más rápido que System.Threading.Tasks.Parallel.ForEach

Entonces, ¿es plinq inherentemente más rápido que Parallel.ForEach? O es específico para la tarea.

// Original Code 
// concurrent dictionary to store results 
var resultDict = new ConcurrentDictionary<string, MyResultType>(); 

Parallel.ForEach(items, item => 
     { 
      resultDict.TryAdd(item.Name, PerformWork(source)); 
     }); 


// new code 

var results = 
      items 
      .AsParallel() 
      .Select(item => new { item.Name, queryResult = PerformWork(item) }) 
      .ToDictionary(kv => kv.SourceName, kv => kv.queryResult); 

Notas: Cada tarea (PerformWork) ahora funciona entre 0 y 200 ms. Solía ​​tomar más tiempo antes de optimizarlo. Es por eso que estaba usando la biblioteca Tasks.Parallel en el primer lugar. Así que pasé de 2 segundos de tiempo total a ~ 100 a 200 ms de tiempo total, realizando aproximadamente el mismo trabajo, solo con diferentes métodos. (Wow LINQ y PLINQ son impresionantes!)

Preguntas:

  1. es la velocidad debido a la utilización de PLINQ vs Parallel.ForEach?
  2. ¿Es simplemente la eliminación de la estructura de datos concurrente (ConcurrentDictionary)? (Porque no necesita sincronizar hilos).
  3. Sobre la base de la respuesta de esta related question

Mientras PLINQ se basa en gran parte en un estilo funcional de los programas sin efectos secundarios, los efectos secundarios son precisamente lo que el TPL es para. Si desea realizar un trabajo en paralelo en lugar de solo buscar/seleccionar cosas en paralelo, use el TPL.

¿Puedo suponer que debido a que mi patrón es básicamente funcional (dando entradas para producir nuevas salidas sin mutación), ese plinq es la tecnología correcta para usar?

Estoy buscando la validación de que mis suposiciones son correctas, o una indicación de que me falta algo.

+0

¿Qué tipo de datos es su variable "artículos" y cuántos elementos hay en ella? –

Respuesta

2

Según la información limitada que ha proporcionado en su muestra (solicité más detalles en un comentario sobre el PO), estoy seguro de que está viendo diferencias debido al algoritmo de partición que se utiliza. Deberías leer en el Chunk Partitioning vs. Range Partitioning en esta publicación de blog donde explica cómo difieren y para qué tipo de trabajo podrían ser más adecuados. Recomiendo leer el artículo de blog y el this one, que incluye un poco más de detalle sobre esos dos tipos junto con otros dos tipos de particiones que se pueden usar, aunque no se apliquen a su muestra, así como proporcionar algunas ayudas visuales para mejorar entender la partición Finalmente, here's yet another blog post que analiza la partición de trabajo y cómo puede afectarlo cuando el algoritmo de partición predeterminado no tiene sentido para su carga de trabajo particular.Esa publicación en realidad se refiere a un gran programa que te ayuda a visualizar las particiones en el trabajo que forman parte de a set of parallel samples from the PFX team.

4

No es posible utilizar estos 2 ejemplos de código para hacer una comparación definitiva entre Parallel.ForEach y PLINQ. Las muestras de código son simplemente demasiado diferentes.

El primer elemento que salta a mí es la primera muestra que usa ConcurrentDictionary y la segunda usa Dictionary. Estos dos tipos tienen usos y características de rendimiento muy diferentes. Para obtener una comparación precisa entre las dos tecnologías, debe ser coherente con los tipos.

+0

¿Cómo sería posible cargar un diccionario genérico regular con Parallel.ForEach? –

+0

@Chris no estoy seguro de que sea posible sin algún tipo de bloqueo. – JaredPar

+0

@JarePar correcto. Ese es el contexto de mi pregunta (aunque probablemente no esté bien indicado). ¿Cómo hago algo en paralelo y devuelvo un diccionario? En este caso, plinq fue mucho más rápido. ¿Es generalizable a una clase de problemas o simplemente una peculiaridad con ConcurrentDictionary? –

Cuestiones relacionadas