2012-03-08 2 views
0

Я пишу приложение, которое поможет улучшить машинные переводы для моей диссертации. Для этого мне требуется огромное количество данных ngram. У меня есть данные из Google, но это не в полезном формате.Оптимизация чтения больших файлов данных в Java

Вот как отформатирован данные от Google:

ngram TAB year TAB match_count TAB page_count TAB volume_count NEWLINE 

Вот что я после:

ngram total_match_count_for_all_years 

Итак, я написал небольшое приложение для запуска через файлы и вытащить ngrams и суммировать данные за несколько лет, чтобы получить общий счет. Это, кажется, прекрасно. Но, так как файлы Google настолько большие (по 1,5 ГБ каждый, их 99). <), это занимает много времени, чтобы пройти через все их.

Вот код:

public class mergeData 
{ 
    private static List<String> storedNgrams = new ArrayList<String>(100001); 
    private static List<String> storedParts  = new ArrayList<String>(100001); 
    private static List<String> toWritePairs = new ArrayList<String>(100001); 
    private static int   rows   = 0; 
    private static int   totalFreq  = 0; 

    public static void main(String[] args) throws Exception 
     { 
      File bigram = new File("data01"); 
      BufferedReader in = new BufferedReader(new FileReader(bigram)); 
      File myFile = new File("newData.txt"); 
      Writer out = new BufferedWriter(new FileWriter(myFile)); 
      while (true)  
       { 
        rows = 0; 
        merge(in, out); 
       } 
     } 

    public static void merge(BufferedReader in, Writer out) throws IOException 
     { 

      while (rows != 1000000) 
       { 
        storedNgrams.add(in.readLine()); 
        rows++; 
       } 

      while (!(storedNgrams.isEmpty())) 
       { 

        storedParts.addAll(new ArrayList<String>(Arrays.asList(storedNgrams.get(0).split("\\s")))); 

        storedNgrams.remove(0); 

       } 
      while (storedParts.size() >= 8) 
       { 
        System.out.println(storedParts.get(0) + " " + storedParts.get(1) + " " + storedParts.get(6) 
          + " " + storedParts.get(7)); 
        if (toWritePairs.size() == 0 && storedParts.get(0).equals(storedParts.get(6)) 
          && storedParts.get(1).equals(storedParts.get(7))) 
         { 

          totalFreq = Integer.parseInt(storedParts.get(3)) + Integer.parseInt(storedParts.get(9)); 

          toWritePairs.add(storedParts.get(0)); 
          toWritePairs.add(storedParts.get(1)); 

          toWritePairs.add(Integer.toString(totalFreq)); 
          storedParts.subList(0, 11).clear(); 

         } 
        else if (!(toWritePairs.isEmpty()) && storedParts.get(0).equals(toWritePairs.get(0)) 
          && storedParts.get(1).equals(toWritePairs.get(1))) 
         { 

          int totalFreq = Integer.parseInt(storedParts.get(3)) 
            + Integer.parseInt(toWritePairs.get(2)); 

          toWritePairs.remove(2); 
          toWritePairs.add(Integer.toString(totalFreq)); 
          storedParts.subList(0, 5).clear(); 
         } 
        else if ((!toWritePairs.isEmpty()) 
          && !(storedParts.get(0).equals(storedParts.get(6)) && storedParts.get(1).equals(
            storedParts.get(7)))) 
         { 
          toWritePairs.add(storedParts.get(0)); 
          toWritePairs.add(storedParts.get(1)); 
          toWritePairs.add(storedParts.get(2)); 
          storedParts.subList(0, 2).clear(); 
         } 

        else if (!(toWritePairs.isEmpty())) 
         { 
          out.append(toWritePairs.get(0) + " " + toWritePairs.get(1) + " " + toWritePairs.get(2) 
            + "\n"); 
          toWritePairs.subList(0, 2).clear(); 

         } 

        out.flush(); 
       } 
     } 

} 

Если у кого есть какие-либо идеи, как улучшить скорость обработки этих файлов, это помогло бы мне безмерно.

+1

Зачем вам когда-либо читать и обрабатывать более одной строки за раз? вы делаете около 5 раз больше работы, чем вам нужно. –

+0

Спасибо, спасибо, спасибо! : D По какой-то причине, делая это по одной строке за раз, мне не приходило в голову. Теперь, когда я удалил все строки и делаю это по очереди, это очень быстро. –

ответ

1

Предлагаю вам обрабатывать данные по ходу движения, а не читать в больших объемах данных, а затем обрабатывать их. Из вашей программы неясно, какую информацию вы пытаетесь извлечь/заполнить.

Даже на быстрой машине я ожидал, что это займет около 20 секунд на файл.

2

Создайте временную таблицу в базе данных. Заполните его строками из файла. При необходимости создайте индекс и дайте базе данных выполнить группировку. Это упростит логику программы и, скорее всего, будет выполняться быстрее.

+0

Дело в том, что с 66 миллионами строк на файл потребовалось бы столько времени, чтобы положить их в таблицу, плюс таблица была бы огромной. –

+1

совет для базы данных, вы не должны создавать индекс, прежде чем вставлять свои огромные данные. Поскольку каждый раз, когда вы вставляете строку, dbms будет переиндексироваться, и это занимает некоторое время для ряда строк. –

Смежные вопросы