2009-12-07 31 views
65

Supongamos que estoy escribiendo un par de archivos en el disco, entre 2 MB y 5 GB. ¿Cuáles son los valores de almacenamiento intermedio sensibles para FileStream?C# FileStream: Tamaño de búfer óptimo para escribir archivos grandes?

¿Es sensato trabajar con buffersizes de varios megabytes, o debería pegarme a los buffers de kilobyte?

+1

¿Por qué no vamos a .Net manejar el tampón y acaba de escribir como usted necesita? – cjk

+1

Solo pruébalo. Escribe un pequeño punto de referencia usando StopWatch y cuéntanos los resultados. –

+4

Sospecho que el "buffer" en cuestión es el buffer que tienes que declarar cuando estás, por ejemplo. copiar de una secuencia a otra (es decir, cuántos bytes 'Leer' y luego 'Escribir' en una iteración). –

Respuesta

43

El tamaño predeterminado de la memoria intermedia es 4 KiB.

También, echar un vistazo aquí: Sequential File Programming Patterns and Performance with .NET

+2

http://msdn.microsoft.com/en-us/library/dd783870.aspx El tamaño predeterminado es '4096' bytes – VMAtm

+3

Acaba de descompilar System.IO.FileStream. interna const int DefaultBufferSize = 4096; – Vladimirs

+2

@VMAtm: esa referencia es falsa (en términos de respuesta a la pregunta sobre qué clase de FileStream normalmente se usa internamente). El tamaño del buffer de CopyTo es sustancialmente mayor, 80 KiB, para ser exactos. Escribí algunas de las características de rendimiento del archivo IO de .NET aquí (http://stackoverflow.com/questions/1540658/net-asynchronous-stream-read-write/19692949#19692949) –

30

Un poco de referencia rápida sobre la base de los espectáculos del Documento de Referencia ningún aumento en el rendimiento en mi sistema de más de 128 KB de tamaño de búfer. Su millaje puede variar, no dude en utilizar el siguiente.

 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 para el benchmark código pero el OP pidió tamaños de búfer de escritura. El enfoque es sólido, sin embargo. –

+1

Hm, su comentario se contradice a sí mismo. Usted dice 'size = 256 KB', pero al mismo tiempo afirma' i = 18', y '2 << 18' es en realidad 512 KB. – Timwi

+0

2 << 18 == 262144 bytes 1024 bytes en un kilo byte, por lo tanto, 256 KB. ¿Qué me estoy perdiendo? – Firestrand

Cuestiones relacionadas