Análise rápida de CSV

Eu tenho um aplicativo de servidor java que baixar arquivo CSV e analisá-lo. A análise pode levar de 5 a 45 minutos e acontece a cada hora. Esse método é um gargalo do aplicativo, portanto, não é uma otimização prematura. O código até agora:

client.executeMethod(method); InputStream in = method.getResponseBodyAsStream(); // this is http stream String line; String[] record; reader = new BufferedReader(new InputStreamReader(in), 65536); try { // read the header line line = reader.readLine(); // some code while ((line = reader.readLine()) != null) { // more code line = line.replaceAll("\"\"", "\"NULL\""); // Now remove all of the quotes line = line.replaceAll("\"", ""); if (!line.startsWith("ERROR"){ //bla bla continue; } record = line.split(","); //more error handling // build the object and put it in HashMap } //exceptions handling, closing connection and reader 

Existe alguma biblioteca que me ajude a acelerar as coisas? Posso melhorar o código existente?

Apache Commons CSV

Você viu o Apache Commons CSV ?

Advertência sobre o uso da split

Lembre-se de que a split só retorna uma exibição dos dados, o que significa que o object de line original não é elegível para a garbage collection enquanto houver uma referência a qualquer uma de suas visualizações. Talvez fazer uma cópia defensiva ajude? ( Relatório de bug do Java )

Também não é confiável no agrupamento de colunas CSV com escape contendo vírgulas

opencsv

Dê uma olhada no opencsv .

Esta postagem do blog, opencsv é um analisador de CSV fácil , tem uso de exemplo.

Além das sugestões feitas acima, acho que você pode tentar melhorar seu código usando alguns segmentos e simultaneidade.

A seguir, a breve análise e a solução sugerida

  1. A partir do código, parece que você está lendo os dados pela rede (mais provavelmente o lib do apache-common-httpclient).
  2. Você precisa se certificar de que o gargalo que você está dizendo não está na transferência de dados pela rede.
  3. Uma maneira de ver é apenas descarregar os dados em algum arquivo (sem análise) e ver quanto é necessário. Isso lhe dará uma idéia de quanto tempo é realmente gasto na análise (quando comparado à observação atual).
  4. Agora, veja como o pacote java.util.concurrent é usado. Alguns dos links que você pode usar são ( 1 , 2 )
  5. O que você pode fazer é que as tarefas que você está fazendo no loop podem ser executadas em um thread.
  6. Usar o conjunto de encadeamentos e a simultaneidade melhorará muito seu desempenho.

Embora a solução envolva algum esforço, mas no final isso irá ajudá-lo.

O problema do seu código é que ele está usando replaceAll e split, que são operações muito caras. Você deve definitivamente considerar o uso de um analisador / leitor csv que faça uma análise de um passo.

Existe uma referência no github

https://github.com/uniVocity/csv-parsers-comparison

que infelizmente é executado sob o java 6. O número é um pouco diferente em java 7 e 8. Eu estou tentando obter mais dados detalhados para o tamanho do arquivo diferente, mas é um trabalho em andamento

veja https://github.com/arnaudroger/csv-parsers-comparison

opencsv

Você deveria dar uma olhada no OpenCSV . Eu esperaria que eles tenham otimizações de desempenho.