J'ai l'obligation de calculer ces deux tâches indépendantes.Arlier, je le faisais en série comme: et la méthode mais depuis que ces 2 et mon J'espérais le code à travailler de manière asynchrone, mais cela fonctionne de manière synchrone. P> p> calculatemd5hash code> est utilisé. Pour calculer les valeurs de hachage MD5 pour les fichiers aussi gros que 16 Go: p>
calcululatemd5hash code> peuvent exécuter en parallèle, j'essayais ceci: p>
calculatemd5 code> méthode ressemble à: p>
3 Réponses :
Ceci est susceptible d'être I / O LIMITED, de sorte que la paralletiquité ne rende probablement pas beaucoup de choses (et même pourrait même ralentir les choses).
Cela dit, le problème avec votre code est que vous n'êtes pas Création de nouvelles tâches pour exécuter le code en arrière-plan (simplement spécifier plutôt que d'essayer de "forcer" il utilisera l'ASYNC, le La solution la plus facile est probablement d'exploiter PLINQ A > via
7 commentaires
J'ai essayé: Files.Asparallel (). Sélectionnez (Calculez TEMD5) .tolist (). Mais le problème est que je dispose de 17 Go de nom de fichier "MyName" et 17 Go avec nom de fichier "noname". Avec la solution fournie, il faut environ 7 minutes, tandis que lorsque je calculais des valeurs de hachage en série, il prenait environ 5 minutes.So, d'une manière dont la performance n'est pas améliorée des byfiles.Asparallall (). Sélectionnez (2). Calcu Latemd5) .tolist ()
Ce n'est pas I / O LIMITED.J'ai une liste de fichiers de liste
@ user11708636
Depuis que j'ai la RAM de 32 Go .1) Est-ce que la programmation parallèle prendra plus de temps que la programmation en série en raison de la RAM insuffisante? 2) Il sera donc préférable d'exécuter ces 2 tâches séquentielles plutôt que parallèlement?
@ user11708636 Dans ce cas particulier, oui: car il est obligé d'E / S, il est plus rapide de traiter les fichiers séquentiellement depuis que vous essayez de lire simultanément deux fichiers. Il est possible d'accélérer cela si vous pouvez lire des morceaux à partir d'un fichier et que différents morceaux sont traités par différents threads - mais vous ne pouvez pas le faire avec
** Notez que la lecture des fichiers simultanément peut être plus rapide dans certains cas **. Mais puisque la transformation utilise RAM de 32 Go, donc le problème des E / S ne continuera-t-il pas, mais dans une légère mesure moindre?
@ user11708636 Le traitement n'utilise pas 32g de RAM - le fichier est traité en morceaux. Vous n'auriez besoin que de tout ce que la RAM si vous lisez chaque fichier dans la mémoire avant de le traiter. Cependant, vous pouvez lire le fichier dans un fil et le traiter dans un fil séparé. Je posterai cette approche comme une réponse séparée dans une minute ou deux. async code> ne crée aucun thread). p>
Ce n'est pas I / O LIMITE.J'ai une liste de liste
File.OpenRead (nom de fichier) code > qui fait des E / S. Étant donné que les fichiers sont de 17 Go chacun, vous auriez besoin d'au moins 34 Go de RAM si vous maintenez les données en mémoire ... It est i> E / S Bound, et le fait qu'il reste plus lent lors de la lecture de la Les fichiers simultanément en résultent de cela.
MD5.Compeauhash () code>. Notez que la lecture des fichiers simultanément peut i> être plus rapide dans certains cas, par ex. Si les fichiers sont sur deux disques durs différents ou si elles sont sur un SSD.
Vous pouvez modifier la fonction de fonction en tâche, puis attendez le résultat.
private async Task<string> CalculateMD5(string filename) { return await Task.Run(() => { using (var md5 = MD5.Create()) { using (var stream = File.OpenRead(filename)) { var hash = md5.ComputeHash(stream); return BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant(); } } }); }
Un moyen d'accélérer ce haut consiste à utiliser un double tampon de sorte que un thread peut être lu dans le fichier dans un tampon, tandis que le MD5 est calculé pour un autre tampon.
Ceci vous permet de chevaucher le i / O avec le calcul. P>
Le meilleur moyen de le faire serait d'avoir une tâche unique qui était responsable du calcul du MD5 pour tous les blocs de données, mais comme cela complique un peu le code (et n'est pas susceptible de donner beaucoup de résultats de bien meilleurs), je vais plutôt créer une nouvelle tâche pour chaque bloc. P>
Le code ressemble à ceci: p>
ComputeMd5Async() Took 00:00:04.8066365 49, 54, 154, 19, 115, 198, 28, 163, 5, 182, 183, 91, 2, 5, 241, 253 ComputeMd5() Took 00:00:06.9654982 49, 54, 154, 19, 115, 198, 28, 163, 5, 182, 183, 91, 2, 5, 241, 253 ComputeMd5Async() Took 00:00:04.7018911 49, 54, 154, 19, 115, 198, 28, 163, 5, 182, 183, 91, 2, 5, 241, 253 ComputeMd5() Took 00:00:07.3552470 49, 54, 154, 19, 115, 198, 28, 163, 5, 182, 183, 91, 2, 5, 241, 253 ComputeMd5Async() Took 00:00:04.6536709 49, 54, 154, 19, 115, 198, 28, 163, 5, 182, 183, 91, 2, 5, 241, 253 ComputeMd5() Took 00:00:06.9807878 49, 54, 154, 19, 115, 198, 28, 163, 5, 182, 183, 91, 2, 5, 241, 253 ComputeMd5Async() Took 00:00:04.7271215 49, 54, 154, 19, 115, 198, 28, 163, 5, 182, 183, 91, 2, 5, 241, 253 ComputeMd5() Took 00:00:07.4089941 49, 54, 154, 19, 115, 198, 28, 163, 5, 182, 183, 91, 2, 5, 241, 253
Une méthode est asynchrone lorsqu'elle renvoie une tâche
incomplète code>. La tâche renvoyée par la méthode
calculaTemd5 code> est toujours terminée, car il n'y a pas de
attendre code> à l'intérieur de cette méthode, il fonctionne donc du début à la fin de manière synchrone. Pour un
gethashasync véritablement asynchrone code> look ici . Btw selon le Directives La méthode
calculatemd5 code> doit être nommée
calculatemd5async code>