2017-08-10 3 views
0

J'ai un processus qui fonctionne sur un grand ensemble de données, traitant les enregistrements dans un Parallel.ForEach puis stockant les résultats dans un ConcurrentQueue<List<string>>. Un enregistrement est donc traité et chaque champ de l'enregistrement génère une chaîne, qui est ensuite ajoutée au List. A la fin de l'enregistrement, List est alors Enqueued, et un traitement supplémentaire est effectué sur le ConcurrentQueue contenant tous les enregistrements traités. Après quelques heures de traitement de l'ensemble, j'ai remarqué que mon utilisation du processeur est passé d'une nouvelle vague à rester assez élevé, et le temps de traiter un groupe d'enregistrements commence à croître.Une collection évolutive pour un grand ensemble de données indéterminé

Mon hypothèse ici est que le List est rempli à capacité, puis copié dans un nouveau plus grand List. Au fur et à mesure que la taille du processeur augmente, le cycle d'initialisation augmente. L'ensemble de données sur lequel je travaille est de taille indéterminée, en ce sens que chaque enregistrement a un nombre variable d'enregistrements enfants. Le nombre d'enregistrements parent est généralement de l'ordre de 500k. Donc, ma première pensée est d'initialiser le List au Count des enregistrements parent. Le List devrait encore croître en raison des dossiers des enfants, mais il devrait au moins croître moins souvent. Mais existe-t-il d'autres alternatives de collection à List qui évolue mieux? Ou une approche différente de mon premier instinct qui me semble meilleur?

Répondre

1

Une requête concurrente est implémentée en tant que liste liée et n'a pas besoin d'être redimensionnée pour la capacité (contrairement à la file d'attente normale). Donc, votre problème sera ailleurs.

Vous voudrez peut-être examiner la quantité de mémoire utilisée et le taux de récupération de place causée par le nettoyage des listes traitées.

Autres conseils:

  • s'il y a beaucoup de manipulation de chaîne lors de la construction de la chaîne à partir d'un champ, utilisez StringBuilder (si vous ne faites pas déjà).
  • S'il y a beaucoup de champs dans un enregistrement et que vous avez un moyen de savoir à l'avance combien: utilisez un tableau par enregistrement au lieu d'une liste, ou définissez la capacité List à une valeur pour toutes les chaînes de l'enregistrement .
+0

Bon à savoir sur la ConcurrentQueue. Je vais vérifier les pourboires sur les cordes elles-mêmes (ceci est une base de code que je viens de mettre en place maintenant qu'il est en difficulté). Le réglage de la capacité sur la liste est définitivement faisable, car le nombre de champs est statique entre les enregistrements. – bcwiniger

+2

Dans ce cas, utilisez un tableau par enregistrement au lieu d'une liste (est légèrement plus rapide) –