Pergunta

Então, eu tenho um número "grande" de "muito grande" arquivos ASCII de dados numéricos (gigabytes ao todo), e meu programa terá de processar a totalidade do que sequencialmente pelo menos uma vez.

Algum conselho sobre como armazenar / carregar os dados? Eu tenho pensado de converter os arquivos para binário para torná-los menores e para carregamento mais rápido.

Devo carregar tudo na memória de uma só vez?
Se não, está abrindo o que é uma boa maneira de carregar os dados parcialmente
Quais são algumas dicas de eficiência Java relevantes?

Foi útil?

Solução

Então, o que se o processamento requer pulando nos dados para vários arquivos e vários buffers? É constante abertura e fechamento de arquivos binários que vão tornar-se caro?

Eu sou um grande fã de 'memória mapeada I / O' , também conhecido como 'buffers de bytes direta' . Em Java, eles são chamados mapeada Byte Buffers são fazem parte de java.nio. (Basicamente, este mecanismo utiliza o sistema de paginação de memória virtual do sistema operacional para 'mapa' seus arquivos e apresentá-los de forma programática como buffers de bytes. O novo sistema vai gerenciar movendo os bytes de / para disco e memória auto-magicamente e muito rapidamente.

Eu sugiro que esta abordagem, porque a) ele trabalha para mim, e b) ele vai deixar você se concentrar em seu algoritmo e deixar a JVM, OS e negócio de hardware com a otimização de desempenho. Tudo para muitas vezes, eles sabem o que é melhor mais do que nós programadores humildes. ;)

Como você usaria MBBs no seu contexto? Basta criar uma MBB para cada um dos seus arquivos e lê-los como quiser. Você só vai precisar para armazenar seus resultados. .

BTW: Quantos dados você está lidando, em GB? Se ele é mais do que 3-4GB, então isso não vai funcionar para você em uma máquina de 32 bits como a implementação MBB é ré no espaço de memória endereçável pela arquitetura de plataforma. A máquina de 64 bits e OS irá levá-lo para 1TB ou 128TB de dados mappable.

Se você está pensando sobre o desempenho, então sei Kirk Pepperdine Ele está envolvido com um site, www.JavaPerformanceTuning.com, que tem mais alguns detalhes MBB (a pouco famoso guru desempenho Java.): NIO dicas de desempenho e outro Java relacionados com o desempenho coisas.

Outras dicas

Você pode querer ter um olhar para as entradas no ampla localizador Projeto (fazer uma pesquisa no google por " wide finder" java ).

O localizador Ampla envolve a leitura sobre lotes de linhas em arquivos de log, por isso olhar para as implementações de Java e ver o que funcionou e não funcionou lá.

Você poderia converter em binário, mas então você tem 1+ algo cópias dos dados, se você precisa manter o torno originais.

Pode ser prático para construir algum tipo de índice em cima de seus dados ASCII originais, de modo que se você precisa passar por os dados novamente, você pode fazê-lo mais rápido em tempos posteriores.

Para responder às suas perguntas em ordem:

Devo carregar tudo na memória de uma só vez?

Não, se não tem que. para alguns arquivos, você pode ser capaz de, mas se você está apenas processar sequencialmente, basta fazer algum tipo de tamponada ler as coisas, um por um, armazenar tudo o que você precisa ao longo do caminho.

Se não, está abrindo o que é uma boa maneira de carregar os dados parcialmente?

BufferedReaders / etc é mais simples, embora você poderia olhar mais profundo sobre FileChannel / etc para usar memorymapped I / O para percorrer janelas dos dados de cada vez.

Quais são algumas dicas de eficiência Java relevantes?

Isso realmente depende do que você está fazendo com os dados em si!

Sem qualquer esclarecimentos adicionais sobre o tipo de processamento está acontecendo, aqui estão algumas reflexões gerais de quando eu ter feito um trabalho semelhante.

  1. Escrever um protótipo de sua aplicação (talvez até mesmo "um para jogar fora") que realizar alguma operação arbitrária no seu conjunto de dados. Ver o quão rápido ele vai. Se a coisa mais simples mais ingênuo que você pode pensar é aceitavelmente rápido, não se preocupe!

  2. Se a abordagem ingênua não trabalho, considere o pré-processamento dos dados para que execuções subseqüentes será executado em um comprimento de tempo aceitável. Você menciona ter que "pular" no conjunto de dados um pouco. Existe alguma maneira de pré-processo que fora? Ou, um passo de pré-processamento pode ser para gerar ainda mais dados - dados de índice - que fornece byte precisas informações de localização sobre as seções críticas, necessárias de seu conjunto de dados. Então, sua corrida de processamento principal pode utilizar esta informação para pular direto para os dados necessários.

Assim, para resumir, a minha abordagem seria tentar algo simples agora e ver o que os olhares de desempenho semelhante. Talvez ele vai ficar bem. Caso contrário, olhar para o processamento dos dados em várias etapas, poupando as operações mais caras para pré-processamento frequentes.

Do not "tudo carregar na memória". Apenas executar acessos de arquivo e deixá página de disco do sistema operacional cache de decidir quando você começa a realmente puxar as coisas diretamente da memória.

Esta depende muito dos dados no arquivo. Grandes mainframes têm feito de dados sequenciais de processamento por um longo tempo, mas eles normalmente não usar acesso aleatório para os dados. Eles só puxá-lo em uma linha de cada vez e processo que muito antes de continuar.

Para acesso aleatório muitas vezes é melhor para construir objetos com cache wrappers que sabem onde no arquivo os dados de que precisam para construção é. Quando necessário que ler esses dados em e construir-se. Desta forma, quando a memória está apertado, você pode simplesmente começar a matar coisas fora sem se preocupar muito sobre não ser capaz de recuperá-lo mais tarde.

Você realmente não têm nos dado informações suficientes para ajudá-lo. Você precisa carregar cada arquivo em seu entiretly, a fim de processá-lo? Ou você pode processá-lo linha por linha?

Ao carregar um arquivo inteiro de uma vez é provável que resulte num desempenho fraco, mesmo para arquivos que não são muito grandes. Sua melhor aposta é para definir um tamanho do buffer que funciona para você e ler / processar os dados de um buffer de cada vez.

Eu encontrei Informatica para ser uma ferramenta de processamento de dados extremamente útil. A boa notícia é que as versões mais recentes até mesmo permitir transformações Java. Se você está lidando com terabytes de dados, talvez seja hora de desembolsar para as ferramentas de ETL best-of-breed.

Eu estou supondo que você quer fazer alguma coisa com os resultados do tratamento aqui, como armazená-lo em algum lugar.

Se os dados numéricos é regularmente amostrados e que você precisa fazer de acesso aleatório considerar armazená-los em um quadtree .

Eu recomendo alavancando fortemente Expressões Regulares e olhando para o pacote IO nio "novo" para entrada mais rápida. Em seguida, ele deve ir tão rapidamente como você pode realisticamente esperar Gigabytes de dados para ir.

Se possível, obter os dados em um banco de dados. Em seguida, você pode aproveitar toda a indexação, armazenamento em cache, pinagem memória, e outras funcionalidades disponíveis para você lá.

Se você precisar acessar os dados mais de uma vez, carregá-lo em um banco de dados. A maioria dos bancos de dados têm algum tipo de utilitário de carga a granel. Se os dados podem caber na memória, e você não precisa mantê-lo em torno ou acessá-lo que, muitas vezes, você pode provavelmente escrita simples algo em Perl ou a sua linguagem de programação favorita.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top