Die optimale Puffergröße hängt mit einer Reihe von Faktoren zusammen: Dateisystemblockgröße, CPU-Cache-Größe und Cache-Latenz.
Die meisten Dateisysteme sind für die Verwendung von Blockgrößen von 4096 oder 8192 konfiguriert. Wenn Sie Ihre Puffergröße so konfigurieren, dass Sie einige Bytes mehr als den Plattenblock lesen, können die Vorgänge mit dem Dateisystem theoretisch äußerst ineffizient sein (dh wenn Sie dies tun) Wenn Sie Ihren Puffer so konfiguriert haben, dass er jeweils 4100 Byte liest, würde jeder Lesevorgang 2 Blocklesevorgänge durch das Dateisystem erfordern. Wenn sich die Blöcke bereits im Cache befinden, zahlen Sie den Preis für RAM -> L3 / L2-Cache-Latenz. Wenn Sie Pech haben und die Blöcke noch nicht im Cache sind, zahlen Sie auch den Preis für die Disk-> RAM-Latenz.
Aus diesem Grund sehen Sie die meisten Puffer mit einer Größe von 2 und im Allgemeinen größer (oder gleich) der Plattenblockgröße. Dies bedeutet, dass einer Ihrer Stream-Lesevorgänge zu mehreren Lesevorgängen von Festplattenblöcken führen kann. Diese Lesevorgänge verwenden jedoch immer einen vollständigen Block - keine verschwendeten Lesevorgänge.
Dies ist in einem typischen Streaming-Szenario ziemlich ausgeglichen, da der Block, der von der Festplatte gelesen wird, beim nächsten Lesen immer noch im Speicher verbleibt (wir führen hier schließlich sequentielle Lesevorgänge durch) Bezahlen des RAM -> L3 / L2-Cache-Latenzpreises beim nächsten Lesevorgang, nicht jedoch der Festplatten-> RAM-Latenz. In Bezug auf die Größenordnung ist die Disk-> RAM-Latenz so langsam, dass sie jede andere Latenz, mit der Sie möglicherweise zu tun haben, ziemlich überfüllt.
Ich vermute also, dass Sie, wenn Sie einen Test mit verschiedenen Cache-Größen durchgeführt haben (dies nicht selbst getan haben), wahrscheinlich einen großen Einfluss der Cache-Größe bis zur Größe des Dateisystemblocks feststellen werden. Darüber hinaus vermute ich, dass sich die Dinge ziemlich schnell beruhigen würden.
Hier gibt es eine Menge Bedingungen und Ausnahmen - die Komplexität des Systems ist tatsächlich erstaunlich (nur L3 -> L2-Cache-Übertragungen in den Griff zu bekommen, ist erstaunlich komplex und ändert sich mit jedem CPU-Typ).
Dies führt zu der Antwort aus der realen Welt: Wenn Ihre App zu 99% verfügbar ist, stellen Sie die Cache-Größe auf 8192 ein und fahren Sie fort (noch besser, wählen Sie die Kapselung gegenüber der Leistung und verwenden Sie BufferedInputStream, um die Details auszublenden). Wenn Sie zu 1% der Apps gehören, die stark vom Festplattendurchsatz abhängig sind, erstellen Sie Ihre Implementierung so, dass Sie verschiedene Strategien für die Festplatteninteraktion austauschen und die Regler und Wählscheiben bereitstellen können, mit denen Ihre Benutzer testen und optimieren können (oder einige davon entwickeln können) selbstoptimierendes System).