2013-01-22 5 views
1

Je veux créer beaucoup (1 million) de petits fichiers aussi rapidement que possible, c'est ce que je fais maintenant:La meilleure façon de créer beaucoup de petits fichiers?

for(long i = 0; i < veryVeryLong; i++){ 
    using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.None)) { 
     byte[] bytes = GetFileContent(i); // no matter 
     fs.Write(bytes, 0, bytes.Length); 
    } 
} 

Puis-je accélérer?

MISE À JOUR

droit roomaroo, je dois utiliser en parallèle, mais je l'ai combiné avec ma fonction et cela a un bien meilleur résultat. Code:

Parallel.For(0, veryVeryLogn, (i) => { 
    using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.None)) { 
     byte[] bytes = GetFileContent(i); // no matter 
     fs.Write(bytes, 0, bytes.Length); 
    } 
}); 
+0

Vous pourriez quelque chose en parallèle. – ChrisBint

+0

pas sûr si peut vous aider .. mais il y a une ligne de commande utils pour créer des fichiers .. "fichier fsutil createnew" – 2GDev

+1

Depuis que vous utilisez C#, vous voudrez peut-être regarder cette question: http://stackoverflow.com/questions/8979686/le plus rapide-pour-créer-des-fichiers-en-c-sharp? rq = 1 –

Répondre

3

Comme suggéré par ChrisBint, utilisez une boucle parallèle.

J'ai créé trois méthodes pour écrire les fichiers (code ci-dessous). On utilise votre code ci-dessus, on utilise File.WriteAllBytes (...) - les deux utilisent une boucle for traditionnelle.

La troisième implémentation utilisait une boucle parallèle.

Voici les temps pour créer 1000 fichiers:

FileStream: 2658ms

File.WriteAllBytes: 2555ms

Parallel.For: 617ms

Ainsi, la boucle parallèle est quatre fois plus rapide que la mise en œuvre la plus lente. Évidemment, cela varie en fonction du matériel et vos résultats dépendront beaucoup de votre CPU et de votre disque.

Voici le code:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Diagnostics; 
using System.Threading.Tasks; 

namespace FileCreator 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string folder = @"d:\temp"; 

      Clean(folder); 
      CreateWithParallelFileWriteBytes(folder); 

      Clean(folder); 
      CreateWithFileStream(folder); 

      Clean(folder); 
      CreateWithFileWriteBytes(folder); 
     } 

     private static void Clean(string folder) 
     { 
      if (Directory.Exists(folder)) 
      { 
       Directory.Delete(folder, true); 
      } 

      Directory.CreateDirectory(folder); 
     } 

     private static byte[] GetFileContent(int i) 
     { 
      Random r = new Random(i); 
      byte[] buffer = new byte[1024]; 
      r.NextBytes(buffer); 
      return buffer; 
     } 

     private static void CreateWithFileStream(string folder) 
     { 
      var sw = new Stopwatch(); 
      sw.Start(); 

      for (int i = 0; i < 1000; i++) 
      { 
       string path = Path.Combine(folder, string.Format("file{0}.dat", i)); 

       using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.None)) 
       { 
        byte[] bytes = GetFileContent(i); 
        fs.Write(bytes, 0, bytes.Length); 
       } 
      } 

      Console.WriteLine("Time for CreateWithFileStream: {0}ms", sw.ElapsedMilliseconds); 
     } 

     private static void CreateWithFileWriteBytes(string folder) 
     { 
      var sw = new Stopwatch(); 
      sw.Start(); 

      for (int i = 0; i < 1000; i++) 
      { 
       string path = Path.Combine(folder, string.Format("file{0}.dat", i)); 
       File.WriteAllBytes(path, GetFileContent(i)); 
      } 

      Console.WriteLine("Time for CreateWithFileWriteBytes: {0}ms", sw.ElapsedMilliseconds); 
     } 

     private static void CreateWithParallelFileWriteBytes(string folder) 
     { 
      var sw = new Stopwatch(); 
      sw.Start(); 

      Parallel.For(0, 1000, (i) => 
      { 
       string path = Path.Combine(folder, string.Format("file{0}.dat", i)); 
       File.WriteAllBytes(path, GetFileContent(i)); 
      }); 

      Console.WriteLine("Time for CreateWithParallelFileWriteBytes: {0}ms", sw.ElapsedMilliseconds); 
     } 
    } 
} 
+0

Y a-t-il un changement de temps si vous exécutez la version parallèle en premier? Le fichier de création est parfois plus rapide si le fichier est déjà sur le disque. –

+0

Ne semble pas affecter le temps. C'est encore ~ ​​600ms pour la version parallèle. – roomaroo

+0

J'ai mis à jour le code afin qu'il supprime le dossier de sortie entre chaque test pour rendre les choses plus justes. Les temps sont sensiblement les mêmes (2715ms/2608ms/602ms). – roomaroo

Questions connexes