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:
- es la velocidad debido a la utilización de PLINQ vs Parallel.ForEach?
- ¿Es simplemente la eliminación de la estructura de datos concurrente (ConcurrentDictionary)? (Porque no necesita sincronizar hilos).
- 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.
¿Qué tipo de datos es su variable "artículos" y cuántos elementos hay en ella? –