O tamanho ideal do buffer está relacionado a várias coisas: tamanho do bloco do sistema de arquivos, tamanho do cache da CPU e latência do cache.
A maioria dos sistemas de arquivos está configurada para usar tamanhos de bloco de 4096 ou 8192. Em teoria, se você configurar o tamanho do buffer para ler alguns bytes a mais do que o bloco de disco, as operações com o sistema de arquivos podem ser extremamente ineficientes (por exemplo, se você configurou seu buffer para ler 4100 bytes de cada vez, cada leitura exigiria 2 leituras de bloco pelo sistema de arquivos). Se os blocos já estiverem no cache, você acaba pagando o preço da RAM -> latência do cache L3 / L2. Se você não tiver sorte e os blocos ainda não estiverem no cache, pagará o preço da latência do disco-> RAM também.
É por isso que você vê a maioria dos buffers dimensionados com uma potência de 2 e geralmente maior que (ou igual ao) tamanho do bloco de disco. Isso significa que uma de suas leituras de fluxo pode resultar em várias leituras de bloco de disco - mas essas leituras sempre usarão um bloco completo - nenhuma leitura desperdiçada.
Agora, isso é bastante compensado em um cenário típico de streaming, porque o bloco que é lido do disco ainda estará na memória quando você clicar na próxima leitura (afinal, estamos fazendo leituras sequenciais aqui) - então você acaba pagando o preço da latência do cache RAM -> L3 / L2 na próxima leitura, mas não a latência do disco-> RAM. Em termos de ordem de magnitude, a latência do disco-> RAM é tão lenta que praticamente inverte qualquer outra latência com a qual você esteja lidando.
Portanto, suspeito que, se você executou um teste com diferentes tamanhos de cache (provavelmente não o fez), provavelmente encontrará um grande impacto no tamanho do cache até o tamanho do bloco do sistema de arquivos. Acima disso, suspeito que as coisas se estabilizariam rapidamente.
Há uma tonelada condições e exceções aqui - as complexidades do sistema são realmente surpreendentes (apenas controlar as transferências de cache L3 -> L2 é incrivelmente complexo e muda com todos os tipos de CPU).
Isso leva à resposta do 'mundo real': se seu aplicativo estiver em 99%, defina o tamanho do cache como 8192 e siga em frente (melhor ainda, escolha o encapsulamento sobre o desempenho e use BufferedInputStream para ocultar os detalhes). Se você estiver no 1% dos aplicativos que são altamente dependentes da taxa de transferência do disco, elabore sua implementação para que você possa trocar diferentes estratégias de interação do disco e forneça os botões e discagens para permitir que seus usuários testem e otimizem (ou apresentem algumas sistema de auto-otimização).
Sim, provavelmente depende de várias coisas - mas duvido que faça muita diferença. Costumo optar por 16K ou 32K como um bom equilíbrio entre uso e desempenho da memória.
Observe que você deve ter um bloco try / finalmente no código para garantir que o fluxo seja fechado, mesmo que uma exceção seja lançada.
fonte
Na maioria dos casos, isso realmente não importa muito. Basta escolher um bom tamanho, como 4K ou 16K, e ficar com ele. Se você acredita que esse é o gargalo do seu aplicativo, comece a criar perfis para encontrar o tamanho ideal do buffer. Se você escolher um tamanho muito pequeno, perderá tempo realizando operações de E / S e chamadas de funções extras. Se você escolher um tamanho muito grande, começará a ver muitas falhas de cache, o que realmente o tornará mais lento. Não use um buffer maior que o tamanho do cache L2.
fonte
No caso ideal, devemos ter memória suficiente para ler o arquivo em uma operação de leitura. Esse seria o melhor desempenho, porque deixamos o sistema gerenciar o Sistema de Arquivos, as unidades de alocação e o HDD à vontade. Na prática, você tem a sorte de conhecer os tamanhos de arquivo antecipadamente, basta usar o tamanho médio do arquivo arredondado para 4K (unidade de alocação padrão no NTFS). E o melhor de tudo: crie uma referência para testar várias opções.
fonte
Você pode usar os BufferedStreams / readers e, em seguida, usar seus tamanhos de buffer.
Acredito que o BufferedXStreams esteja usando 8192 como o tamanho do buffer, mas, como Ovidiu disse, você provavelmente deve executar um teste em várias opções. Realmente vai depender das configurações do sistema de arquivos e do disco, quais são os melhores tamanhos.
fonte
A leitura de arquivos usando o FileChannel e o MappedByteBuffer do Java NIO provavelmente resultará em uma solução muito mais rápida do que qualquer solução que envolva o FileInputStream. Basicamente, mapeie arquivos grandes de memória e use buffers diretos para arquivos pequenos.
fonte
Na fonte do BufferedInputStream você encontrará: private static int DEFAULT_BUFFER_SIZE = 8192;
Portanto, é bom você usar esse valor padrão.
Mas se você conseguir descobrir mais algumas informações, obterá respostas mais valiosas.
Por exemplo, seu adsl talvez prefira um buffer de 1454 bytes, devido à carga útil do TCP / IP. Para discos, você pode usar um valor que corresponda ao tamanho do bloco do seu disco.
fonte
Como já mencionado em outras respostas, use BufferedInputStreams.
Depois disso, acho que o tamanho do buffer não importa. O programa está vinculado à E / S e o tamanho crescente do buffer em relação ao padrão BIS não causará grande impacto no desempenho.
Ou o programa é vinculado à CPU dentro do MessageDigest.update () e a maior parte do tempo não é gasta no código do aplicativo, portanto, ajustá-lo não ajudará.
(Hmm ... com vários núcleos, os threads podem ajudar.)
fonte
1024 é apropriado para uma ampla variedade de circunstâncias, embora na prática você possa ver melhor desempenho com um tamanho de buffer maior ou menor.
Isso dependeria de vários fatores, incluindo o tamanho do bloco do sistema de arquivos e o hardware da CPU.
Também é comum escolher uma potência de 2 para o tamanho do buffer, uma vez que a maioria dos hardwares subjacentes é estruturada com tamanhos de bloco e cache com capacidade de 2. As classes Buffered permitem especificar o tamanho do buffer no construtor. Se nenhum for fornecido, eles usarão um valor padrão, que é uma potência de 2 na maioria das JVMs.
Independentemente de qual tamanho de buffer você escolher, o maior aumento de desempenho que você verá está passando do acesso a arquivos sem buffer para buffer. Ajustar o tamanho do buffer pode melhorar um pouco o desempenho, mas, a menos que você esteja usando um tamanho de buffer extremamente pequeno ou muito grande, é improvável que tenha um impacto significativo.
fonte