Optymalny rozmiar bufora jest związany z wieloma czynnikami: rozmiarem bloku systemu plików, rozmiarem pamięci podręcznej procesora i opóźnieniem pamięci podręcznej.
Większość systemów plików jest skonfigurowana tak, aby używać bloków o rozmiarach 4096 lub 8192. Teoretycznie, jeśli skonfigurujesz rozmiar bufora tak, aby odczytać kilka bajtów więcej niż blok dysku, operacje na systemie plików mogą być bardzo nieefektywne (tj. Jeśli skonfigurował bufor do odczytu 4100 bajtów na raz, każdy odczyt wymagałby 2 odczytów bloków przez system plików). Jeśli bloki są już w pamięci podręcznej, ostatecznie płacisz cenę pamięci RAM -> opóźnienie pamięci podręcznej L3 / L2. Jeśli masz pecha i bloki nie są jeszcze w pamięci podręcznej, zapłacisz również cenę za dysk-> opóźnienie pamięci RAM.
Dlatego większość buforów jest traktowana jako potęga 2 i ogólnie jest większa (lub równa) rozmiarowi bloku dysku. Oznacza to, że jeden z odczytów strumienia może spowodować wielokrotne odczyty bloków dysku - ale te odczyty zawsze będą używać pełnego bloku - bez zmarnowanych odczytów.
Teraz jest to nieco przesunięte w typowym scenariuszu przesyłania strumieniowego, ponieważ blok, który jest odczytywany z dysku, nadal będzie w pamięci, gdy trafisz na następny odczyt (w końcu wykonujemy tutaj odczyty sekwencyjne) - więc kończysz płacenie pamięci RAM -> cena opóźnienia pamięci podręcznej L3 / L2 przy następnym odczycie, ale nie za opóźnienie dysku-> RAM. Jeśli chodzi o rząd wielkości, opóźnienie dysku-> pamięci RAM jest tak wolne, że prawie całkowicie zapycha wszelkie inne opóźnienia, z którymi możesz mieć do czynienia.
Podejrzewam więc, że jeśli przeprowadziłeś test z różnymi rozmiarami pamięci podręcznej (sam tego nie zrobiłem), prawdopodobnie zauważysz duży wpływ rozmiaru pamięci podręcznej do rozmiaru bloku systemu plików. Poza tym podejrzewam, że sytuacja szybko się wyrównuje.
Jest tu mnóstwo warunków i wyjątków - złożoność systemu jest w rzeczywistości dość oszałamiająca (samo uzyskanie uchwytu dla transferów pamięci podręcznej L3 -> L2 jest zadziwiająco skomplikowane i zmienia się z każdym typem procesora).
Prowadzi to do odpowiedzi „w prawdziwym świecie”: jeśli Twoja aplikacja jest dostępna w 99%, ustaw rozmiar pamięci podręcznej na 8192 i przejdź dalej (jeszcze lepiej, wybierz hermetyzację zamiast wydajności i użyj BufferedInputStream, aby ukryć szczegóły). Jeśli znajdujesz się w 1% aplikacji, które są w dużym stopniu zależne od przepustowości dysku, stwórz swoją implementację, aby móc zamienić różne strategie interakcji z dyskiem oraz zapewnij pokrętła i pokrętła, aby umożliwić użytkownikom testowanie i optymalizowanie (lub wymyślanie niektórych system samooptymalizacji).