La taille optimale du tampon est liée à un certain nombre de choses: la taille du bloc du système de fichiers, la taille du cache du processeur et la latence du cache.
La plupart des systèmes de fichiers sont configurés pour utiliser des tailles de bloc de 4096 ou 8192. En théorie, si vous configurez la taille de votre tampon de manière à lire quelques octets de plus que le bloc de disque, les opérations avec le système de fichiers peuvent être extrêmement inefficaces (c'est-à-dire si vous configuré votre tampon pour lire 4100 octets à la fois, chaque lecture nécessiterait 2 lectures de bloc par le système de fichiers). Si les blocs sont déjà dans le cache, vous finissez par payer le prix de la RAM -> latence du cache L3 / L2. Si vous n'êtes pas chanceux et que les blocs ne sont pas encore en cache, vous payez également le prix de la latence disque-> RAM.
C'est pourquoi vous voyez la plupart des tampons dimensionnés comme une puissance de 2, et généralement supérieure (ou égale) à la taille du bloc de disque. Cela signifie qu'une de vos lectures de flux peut entraîner plusieurs lectures de bloc de disque - mais ces lectures utiliseront toujours un bloc complet - pas de lectures gaspillées.
Maintenant, cela est un peu décalé dans un scénario de streaming typique car le bloc qui est lu à partir du disque sera toujours en mémoire lorsque vous frappez la prochaine lecture (nous faisons des lectures séquentielles ici, après tout) - donc vous vous retrouvez payer la RAM -> prix de latence du cache L3 / L2 à la prochaine lecture, mais pas la latence disque-> RAM. En termes d'ordre de grandeur, la latence disque-> RAM est si lente qu'elle comble à peu près toute autre latence que vous pourriez avoir à gérer.
Donc, je soupçonne que si vous exécutez un test avec différentes tailles de cache (je ne l'ai pas fait moi-même), vous constaterez probablement un impact important de la taille du cache jusqu'à la taille du bloc du système de fichiers. Au-dessus de cela, je soupçonne que les choses se stabiliseraient assez rapidement.
Il y a une tonne de conditions et d'exceptions ici - les complexités du système sont en fait assez stupéfiantes (le simple fait de maîtriser les transferts de cache L3 -> L2 est incroyablement complexe, et cela change avec chaque type de processeur).
Cela conduit à la réponse du `` monde réel '': si votre application est à 99%, définissez la taille du cache sur 8192 et continuez (mieux encore, choisissez l'encapsulation plutôt que les performances et utilisez BufferedInputStream pour masquer les détails). Si vous êtes dans le 1% des applications qui dépendent fortement du débit du disque, concevez votre implémentation afin de pouvoir échanger différentes stratégies d'interaction de disque, et fournissez les boutons et les molettes pour permettre à vos utilisateurs de tester et d'optimiser (ou d'en proposer système d'auto-optimisation).