2009-12-07 7 views
65

Supponiamo che sto scrivendo un paio di file su disco, tra 2 MB e 5 GB. Quali sono i valori del buffer sensibili per FileStream?C# FileStream: dimensioni del buffer ottimali per la scrittura di file di grandi dimensioni?

È ragionevole lavorare con buffer di diversi megabyte, o dovrei attenermi ai buffer di kilobyte?

+1

Perché non lasciare .Net gestire il buffer e basta scrivere come è necessario? – cjk

+1

Provalo. Scrivi un piccolo benchmark usando StopWatch e comunicaci i risultati. –

+4

Sospetto che il "buffer" in questione sia il buffer che devi dichiarare quando sei, ad es. copiare da uno stream ad un altro (cioè quanti byte si leggono e poi scrivere in una iterazione). –

risposta

43

La dimensione del buffer predefinita è 4 KiB.

Inoltre, date un'occhiata qui: Sequential File Programming Patterns and Performance with .NET

+2

http://msdn.microsoft.com/en-us/library/dd783870.aspx La dimensione predefinita è '4096' byte – VMAtm

+3

Appena decompilato System.IO.FileStream. internal const int DefaultBufferSize = 4096; – Vladimirs

+2

@VMAtm: tale riferimento è fasullo (in termini di risposta alla domanda su ciò che la classe FileStream normalmente utilizza internamente). La dimensione del buffer CopyTo è sostanzialmente maggiore, 80 KiB, per la precisione. Ho fatto uno scrupolo su alcune delle caratteristiche delle prestazioni dei file IO di .NET qui (http://stackoverflow.com/questions/1540658/net-asynchronous-stream-read-write/19692949#19692949) –

30

Un po 'di riferimento rapido sulla base del documento si fa riferimento spettacoli alcun aumento in termini di prestazioni sul mio sistema superiori a 128 KB dimensione del buffer. Il tuo chilometraggio può variare, sentiti libero di usare il sotto.

 Stopwatch sw = new Stopwatch(); 
     Random rand = new Random(); // seed a random number generator 
     int numberOfBytes = 2 << 22; //8,192KB File 
     byte nextByte; 
     for (int i = 1; i <= 28; i++) //Limited loop to 28 to prevent out of memory 
     { 
      sw.Start(); 
      using (FileStream fs = new FileStream(
       String.Format(@"C:\TEMP\TEST{0}.DAT", i), // name of file 
       FileMode.Create, // create or overwrite existing file 
       FileAccess.Write, // write-only access 
       FileShare.None,  // no sharing 
       2 << i,    // block transfer of i=18 -> size = 256 KB 
       FileOptions.None)) 
      { 
       for (int j = 0; j < numberOfBytes; j++) 
       { 
        nextByte = (byte)(rand.Next() % 256); // generate a random byte 
        fs.WriteByte(nextByte);    // write it 
       } 
      } 
      sw.Stop(); 
      Console.WriteLine(String.Format("Buffer is 2 << {0} Elapsed: {1}", i, sw.Elapsed)); 
      sw.Reset(); 
     } 
+2

+1 per il benchmark codice ma l'OP ha richiesto dimensioni del buffer di scrittura. L'approccio è sano, comunque. –

+1

Hm, il tuo commento si contraddice. Dite 'size = 256 KB', ma allo stesso tempo dichiarate' i = 18', e '2 << 18' è in realtà 512 KB. – Timwi

+0

2 << 18 == 262144 byte 1024 byte in un byte di kilo, quindi 256 KB. Cosa mi manca? – Firestrand