281 votes

Parallel.ForEach vs Task.Factory.StartNew

Quelle est la différence entre le dessous des extraits de code ? Ne tous les deux être en utilisant les threads threadpool ?

Par exemple si je veux appeler une fonction pour chaque élément dans une collection,

313voto

Reed Copsey Points 315315

La première est une bien meilleure option.

En parallèle.ForEach, en interne, utilise un Partitioner<T> de distribuer votre collection dans les éléments de travail. Il ne fera pas une tâche par élément, mais plutôt ce lot pour abaisser les coûts.

La deuxième option fixera un seul Task par élément dans votre collection. Alors que les résultats seront (presque) la même chose, cela va introduire beaucoup plus de ressources que nécessaire, en particulier pour les grandes collections, et la cause de l'ensemble de l'exécution plus lente.

FYI - L'outil de Partitionnement utilisé peut être contrôlée en utilisant l'une des surcharges en Parallèle.ForEach, si vous le souhaitez. Pour plus de détails, consultez Personnalisé Partitioners sur MSDN.

La principale différence, au moment de l'exécution, est la deuxième loi asynchrone. Cela peut être dupliqué à l'aide de Parallèles.ForEach en faisant:

Task.Factory.StartNew( () => Parallel.ForEach<Item>(items, item => DoSomething(item)));

En faisant cela, vous pourrez toujours profiter de la partitioners, mais ne pas bloquer jusqu'à ce que l'opération est terminée.

97voto

Shivprasad Koirala Points 1327

J'ai fait une petite expérience de l'exécution de la méthode "1000000000" fois avec "Parallèle.Pour" et un "Devoir" des objets.

J'ai mesuré le temps processeur et trouvé Parallèle plus efficace. En parallèle.Pour divise votre tâche dans de petits éléments de travail et les exécute sur tous les cœurs, parallèlement de façon optimale. Alors que la création de beaucoup d'objets de tâche ( pour info TPL va utiliser le thread de mise en commun à l'interne) se déplace à chaque exécution de chaque tâche de créer plus de stress dans la boite qui est évident à partir de l'expérience ci-dessous.

J'ai également réalisé une petite vidéo qui explique de base TPL et a également démontré comment Parallèle.Pour utilise votre base de manière plus efficace http://www.youtube.com/watch?v=No7QqSc5cl8 par rapport à la normale des tâches et des threads.

Expérience 1

Parallel.For(0, 1000000000, x => Method1());

Expérience 2

for (int i = 0; i < 1000000000; i++)
{
    Task o = new Task(Method1);
    o.Start();
}

Processor time comparison

17voto

Sogger Points 2761

Parallel.ForEach optimisera (ne peut pas encore commencer nouveaux threads) bloquent jusqu'à ce que la boucle est terminée, et Task.Factory explicitement créera une nouvelle instance de la tâche pour chaque élément et retourner avant qu’ils soient finis (tâches asynchrones). Parallel.Foreach est beaucoup plus efficace.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X