Comparação de desempenho (Benchmark)

É mais fácil fazer o benchmark do que falar, mas estou chutando que teríamos a seguinte situação:

Tempo gasto:
FileChannel.transferTo < NIO Buffers < BufferedXStream+FileXStream < FileXStream puro

Consumo de memória:
FileChannel.transferTo < FileXStream < BufferedXStream + FileXStream < NIO Bufffers

Consumo de CPU (supondo que, se você tiver um disco ATA, que esteja configurado para usar DMA para reduzir o consumo de CPU em I/O):
FileChannel.transferTo < NIO Buffers < BufferedXStream + FileXStream < FileXStream

É estranho que eu esteja chutando que BufferedXStream + FileXStream consuma menos CPU que FileXStream sozinho (afinal, está executando mais código), mas é que BufferedXStream evita que FileXStream esteja constantemente acessando o sistema operacional via JNI, o que consome um monte de CPU.

Obviamente é necessário fazer o teste, porque na prática aparecem coisas que não são esperadas só pela teoria. (Para explicar os resultados, é preciso mudar a teoria…)

Usar streams de apoio que te dão bufferização são apenas uteis quando se está lendo em blocos muito pequenos, só read() por exemplo, porém se estiver usando bunk read, read(byte[4096]) por exemplo, eles acabam sendo mais lentos por fazer muita copia.

Uma vez eu fiz um teste dr performance com java.nio e java.net p/ velocidade de sockets e ela foi basicamente a mesma para ambos.

As JVMs de hoje são tão avançadas que eliminaram muito do overhead do java.io.

A performace do java.nio é bem melhor quando usamos no lugar de um DataOuputStream, por exemplo, mas para o transporte bruto de dados, quase não tem.

Mais um motivo para eu não ficar usando java.nio a torto e a direito. Além de ela não estar disponível em JDK 1.3, parece que para certas coisas ela não é muito fácil de usar - ver a thread “Taming the NIO Circus” no forum.java.sun.com, Java Programming.

No geral NIO não tem motivos para ser muito mais rápida que java.io, as grandes vantagens são as classes de buffer, os métodos de scatter/gather e um modelo mais escalavel p/ muitos sockets.

Olá

Louds, você deu uma bela simplificada. O java.NIO é muito mais e muito melhor do que só isto. Além dos motivos que você falou, temos ainda a questão do IO não blocado, os arquivos memória mapeada, a facilidade de lock de arquivos, os conceitos de channels e selectors, as transferências channel-to-channel (já citadas por vocês nesta ou em outra pasta) e também a possibilidade de bom ganho de performance em algumas circunstâncias.

O uso do IO em Java ficou hoje um pouco mascarado porque na verdade tudo usa IO, mas poucos programadores escrevem código diretamente. Ai aparece alguém e copia arquivos caracter por caracter. Ainda bem que o sistema operacional não obedece ao pé da letra e tem lá suas defesas.

Parêntesis apenas para registro histórico:[list]Em outro post alguém falou em transferências via DMA. Há muito anos atrás usei isto a partir de dicas de um livro chamado The 8086/8088 family: design, programming and interfacing de John Uffenbeck de 1987 e do livro 8086/8088 User’s manual: Programmer’s and hardware reference da Intel de 1989. Realmente dei uma puta escovada de bits fazendo tudo em assembler e ficou um avião. Porém, meu real intuito era um programa de transferência pela porta serial e o concorrente que eu estava tentando bater era um programa chamado Laplink. Merda! Mesmo usando compressão de dados tipo dicionário LZW, usando DMA e toda minha caixa de ferramentas, o tal Laplink era ainda mais rápido do que o meu. Resumo: não basta saber usar, precisa usar bem e isto parece que eu não consegui.[/list]
[]s
Luca