Archivo de E / S con transmisiones: el mejor tamaño de búfer de memoria

Estoy escribiendo una pequeña biblioteca de E / S para ayudar con un proyecto más grande (pasatiempo). Una parte de esta biblioteca realiza varias funciones en un archivo, que se lee / escribe mediante el objeto FileStream . En cada pase StreamReader.Read(...) ,

Disparo un evento que se utilizará en la aplicación principal para mostrar la información de progreso. El procesamiento que se realiza en el ciclo se cancela, pero no consume demasiado tiempo (podría ser simplemente una copia de archivo simple, por ejemplo, o puede implicar cifrado …).

Mi pregunta principal es: ¿Cuál es el mejor tamaño de buffer de memoria para usar? Pensando en los diseños de discos físicos, pude elegir 2k, que cubriría un tamaño de sector de CD y es un buen múltiplo de un sector de disco duro de 512 bytes. Más arriba en el árbol de abstracción, podría ir a un búfer más grande que podría leer todo un grupo de FAT a la vez. Me doy cuenta de que con las PC de hoy en día, podría ir por una opción más hambrienta de memoria (un par de MiB, por ejemplo), pero luego aumento el tiempo entre las actualizaciones de UI y el usuario percibe una aplicación menos sensible.

Por otro lado, eventualmente espero proporcionar una interfaz similar a los archivos alojados en servidores FTP / HTTP (a través de una red local / fastish DSL). ¿Cuál sería el mejor tamaño de búfer de memoria para aquellos (una vez más, una compensación de “mejor caso” entre la percepción de la capacidad de respuesta frente al rendimiento)?

Los archivos ya están almacenados en el caché del sistema de archivos. Solo tiene que elegir un tamaño de búfer que no obligue a FileStream a realizar la llamada nativa de Windows ReadFile () API para llenar el búfer con demasiada frecuencia. No vaya por debajo de un kilobyte, más de 16 KB es un desperdicio de memoria y antipático para la memoria caché L1 de la CPU (normalmente 16 o 32 KB de datos).

4 KB es una opción tradicional, a pesar de que abarcará exactamente una página de memoria virtual solo por accidente. Es difícil hacer un perfil; terminarás midiendo cuánto tiempo lleva leer un archivo en caché. Que se ejecuta a velocidades de RAM, 5 gigabytes / sy más si los datos están disponibles en la memoria caché. Estará en la memoria caché la segunda vez que ejecute la prueba, y eso no sucederá en un entorno de producción con demasiada frecuencia. File I / O está completamente dominado por la unidad de disco o el NIC y es glacialmente lento, copiar los datos es cacahuetes. 4 KB funcionará bien.

Cuando trato con archivos directamente a través de un objeto de transmisión, normalmente uso 4096 bytes. Parece ser razonablemente efectivo en múltiples áreas de E / S (sistema de archivos local, LAN / SMB , flujo de red, etc.), pero no lo he perfilado ni nada. Hace mucho tiempo, vi varios ejemplos que usan ese tamaño, y se quedó grabado en mi memoria. Sin embargo, eso no significa que sea el mejor.

“Depende”.

Debería probar su aplicación con diferentes tamaños de buffer para determinar si el mejor es el whisky. No puedes adivinar por adelantado.

Supongo que el valor predeterminado es el mejor; por lo tanto, uso 4096B basado en internal const int variable internal const int DefaultBufferSize en la clase FileStream .