Ukuran buffer optimal terkait dengan sejumlah hal: ukuran blok sistem file, ukuran cache CPU, dan latensi cache.
Sebagian besar sistem file dikonfigurasikan untuk menggunakan ukuran blok 4096 atau 8192. Secara teori, jika Anda mengkonfigurasi ukuran buffer sehingga Anda membaca beberapa byte lebih banyak daripada blok disk, operasi dengan sistem file bisa sangat tidak efisien (yaitu jika Anda mengkonfigurasi buffer Anda untuk membaca 4100 byte pada suatu waktu, setiap pembacaan akan membutuhkan 2 blok yang dibaca oleh sistem file). Jika blok sudah dalam cache, maka Anda akhirnya membayar harga RAM -> L3 / L2 cache latency. Jika Anda kurang beruntung dan blok belum ada dalam cache, Anda membayar harga latensi disk-> RAM juga.
Inilah sebabnya mengapa Anda melihat sebagian besar buffer berukuran sebagai kekuatan 2, dan umumnya lebih besar dari (atau sama dengan) ukuran blok disk. Ini berarti bahwa salah satu aliran Anda membaca dapat menghasilkan banyak pembacaan blok disk - tetapi pembacaan tersebut akan selalu menggunakan blok penuh - tidak ada pembacaan yang sia-sia.
Sekarang, ini diimbangi sedikit dalam skenario streaming yang khas karena blok yang dibaca dari disk akan tetap berada di memori ketika Anda menekan membaca berikutnya (setelah semua, kami melakukan membaca berurutan di sini) - sehingga Anda berakhir membayar RAM -> L3 / L2 harga latensi cache pada bacaan berikutnya, tetapi bukan disk-> RAM latensi. Dalam hal urutan besarnya, disk-> RAM latensi sangat lambat sehingga cukup banyak menggantikan latensi lain yang mungkin Anda hadapi.
Jadi, saya menduga bahwa jika Anda menjalankan tes dengan ukuran cache yang berbeda (belum melakukannya sendiri), Anda mungkin akan menemukan dampak besar ukuran cache hingga ukuran blok sistem file. Di atas itu, saya curiga bahwa segala sesuatunya akan naik dengan cepat.
Ada satu ton kondisi dan pengecualian di sini - kompleksitas sistem sebenarnya cukup mengejutkan (hanya menangani L3 -> L2 cache transfer sangat membingungkan, dan itu berubah dengan setiap jenis CPU).
Ini mengarah ke jawaban 'dunia nyata': Jika aplikasi Anda seperti 99% di luar sana, atur ukuran cache ke 8192 dan lanjutkan (bahkan lebih baik, pilih enkapsulasi daripada kinerja dan gunakan BufferedInputStream untuk menyembunyikan detail). Jika Anda berada dalam 1% aplikasi yang sangat bergantung pada throughput disk, buat implementasi Anda sehingga Anda dapat menukar strategi interaksi disk yang berbeda, dan memberikan kenop dan tombol untuk memungkinkan pengguna Anda menguji dan mengoptimalkan (atau menghasilkan beberapa sistem optimalisasi diri).
Ya, itu mungkin tergantung pada berbagai hal - tetapi saya ragu itu akan membuat banyak perbedaan. Saya cenderung memilih 16K atau 32K sebagai keseimbangan yang baik antara penggunaan memori dan kinerja.
Perhatikan bahwa Anda harus memiliki blok coba / akhirnya dalam kode untuk memastikan aliran ditutup bahkan jika ada pengecualian.
sumber
Dalam kebanyakan kasus, itu tidak terlalu menjadi masalah. Pilih saja ukuran yang bagus seperti 4K atau 16K dan tetap menggunakannya. Jika Anda yakin ini adalah hambatan dalam aplikasi Anda, maka Anda harus mulai membuat profil untuk menemukan ukuran buffer yang optimal. Jika Anda memilih ukuran yang terlalu kecil, Anda akan membuang waktu untuk melakukan operasi I / O tambahan dan panggilan fungsi ekstra. Jika Anda memilih ukuran yang terlalu besar, Anda akan mulai melihat banyak kesalahan cache yang benar-benar akan memperlambat Anda. Jangan gunakan buffer yang lebih besar dari ukuran cache L2 Anda.
sumber
Dalam kasus ideal kita harus memiliki cukup memori untuk membaca file dalam satu operasi baca. Itu akan menjadi pemain terbaik karena kami membiarkan sistem mengelola Sistem File, unit alokasi, dan HDD sesuka hati. Dalam praktiknya Anda beruntung mengetahui ukuran file di muka, cukup gunakan ukuran file rata-rata dibulatkan hingga 4K (unit alokasi default pada NTFS). Dan yang terbaik: buat patokan untuk menguji beberapa opsi.
sumber
Anda bisa menggunakan BufferedStreams / pembaca dan kemudian menggunakan ukuran buffer mereka.
Saya percaya BufferedXStreams menggunakan 8192 sebagai ukuran buffer, tapi seperti kata Ovidiu, Anda mungkin harus menjalankan tes pada sejumlah opsi. Itu benar-benar akan tergantung pada konfigurasi sistem file dan disk untuk apa ukuran terbaik.
sumber
Membaca file menggunakan Java NIO FileChannel dan MappedByteBuffer kemungkinan besar akan menghasilkan solusi yang akan jauh lebih cepat daripada solusi apa pun yang melibatkan FileInputStream. Pada dasarnya, memori file peta besar, dan gunakan buffer langsung untuk yang kecil.
sumber
Dalam sumber BufferedInputStream Anda akan menemukan: private static int DEFAULT_BUFFER_SIZE = 8192;
Jadi tidak apa-apa bagi Anda untuk menggunakan nilai default itu.
Tetapi jika Anda bisa mencari tahu lebih banyak informasi, Anda akan mendapatkan jawaban yang lebih berharga.
Sebagai contoh, adsl Anda mungkin lebih suka buffer dari 1454 byte, itu karena payload TCP / IP. Untuk disk, Anda dapat menggunakan nilai yang cocok dengan ukuran blok disk Anda.
sumber
Seperti yang sudah disebutkan dalam jawaban lain, gunakan BufferedInputStreams.
Setelah itu, saya kira ukuran buffer tidak terlalu penting. Entah program terikat I / O, dan semakin besar ukuran buffer di atas standar BIS, tidak akan membuat dampak besar pada kinerja.
Atau program ini terikat CPU di dalam MessageDigest.update (), dan sebagian besar waktu tidak dihabiskan dalam kode aplikasi, jadi mengutak-atik itu tidak akan membantu.
(Hmm ... dengan banyak inti, utas mungkin membantu.)
sumber
1024 sesuai untuk berbagai keadaan, meskipun dalam praktiknya Anda mungkin melihat kinerja yang lebih baik dengan ukuran buffer yang lebih besar atau lebih kecil.
Ini akan tergantung pada sejumlah faktor termasuk ukuran blok sistem file dan perangkat keras CPU.
Juga umum untuk memilih kekuatan 2 untuk ukuran buffer, karena sebagian besar perangkat keras yang mendasarinya disusun dengan blok fle dan ukuran cache yang merupakan kekuatan 2. Kelas Buffered memungkinkan Anda menentukan ukuran buffer dalam konstruktor. Jika tidak ada yang disediakan, mereka menggunakan nilai default, yang merupakan kekuatan 2 di sebagian besar JVM.
Terlepas dari ukuran buffer yang Anda pilih, peningkatan kinerja terbesar yang akan Anda lihat adalah beralih dari akses file tanpa buffer ke buffered. Menyesuaikan ukuran buffer mungkin sedikit meningkatkan kinerja, tetapi kecuali jika Anda menggunakan ukuran buffer yang sangat kecil atau sangat besar, itu tidak akan berdampak signifikan.
sumber