La taille optimale de la mémoire tampon est liée à un certain nombre d'éléments : la taille des blocs 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 du disque, les opérations avec le système de fichiers peuvent être extrêmement inefficaces (par exemple, si vous configurez votre tampon pour lire 4100 octets à la fois, chaque lecture nécessiterait 2 lectures de blocs par le système de fichiers). Si les blocs sont déjà dans le cache, vous payez le prix de la latence RAM -> cache L3/L2. Si vous êtes malchanceux et que les blocs ne sont pas encore dans le cache, vous payez également le prix de la latence disque->RAM.
C'est pourquoi la plupart des tampons sont dimensionnés comme une puissance de 2, et généralement plus grands que (ou égaux à) la taille du bloc du disque. Cela signifie que l'une de vos lectures de flux peut entraîner la lecture de plusieurs blocs de disque - mais ces lectures utiliseront toujours un bloc complet - pas de lectures inutiles.
Ceci est très largement compensé dans un scénario de streaming typique car le bloc lu sur le disque sera toujours en mémoire lors de la lecture suivante (nous faisons des lectures séquentielles ici, après tout) - vous payez donc le prix de la latence RAM -> cache L3/L2 lors de la lecture suivante, mais pas la latence disque->RAM. En termes d'ordre de grandeur, la latence disque->RAM est si lente qu'elle écrase toute autre latence à laquelle vous pourriez être confronté.
Je pense donc que si vous effectuez 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-delà, je pense que les choses se stabiliseraient assez rapidement.
Il existe un 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 d'une complexité époustouflante, et cela change avec chaque type de CPU).
Ceci nous amène à la réponse du "monde réel" : Si votre application est comme 99% des autres, fixez la taille du cache à 8192 et passez à autre chose (mieux encore, choisissez l'encapsulation plutôt que les performances et utilisez BufferedInputStream pour cacher les détails). Si vous faites partie des 1% d'applications qui dépendent fortement du débit du disque, concevez votre implémentation de manière à pouvoir échanger différentes stratégies d'interaction avec le disque, et fournissez les boutons et les cadrans pour permettre à vos utilisateurs de tester et d'optimiser (ou mettez au point un système auto-optimisant).