2012-03-08 7 views
0

私の論文の機械翻訳を改善するためのアプリケーションを作成しています。このためには、膨大な量のngramデータが必要です。私はGoogleからデータを入手しましたが、それは有用なフォーマットではありません。Javaで大きなデータファイルの読み込みを最適化する

ngram TAB year TAB match_count TAB page_count TAB volume_count NEWLINE 

は、ここで私は後だものです::だから

ngram total_match_count_for_all_years 

、私は、ファイルを介して実行し、引き出すための小さなアプリケーションを書いたここで

は、Googleのデータをフォーマットする方法です総計を得るために、データを複数年にわたって集計します。それはうまくいくようです。しかし、Googleのファイルは非常に大きいので(1.5GBごと!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行にするのは私には起こりませんでした。すべての行を削除したので、一度に1行ずつ行っています。これは非常に高速です。 –

答えて

1

大量のデータを読み込んで後で処理するのではなく、データを処理することをお勧めします。あなたのプログラムから、どの情報を抽出/集約しようとしているかははっきりしていません。

高速のマシンでも、ファイルごとに約20秒かかることが予想されます。

2

データベースに一時テーブルを作成します。ファイルの行を挿入します。必要に応じて索引を作成し、データベースにグループ化を実行させます。これはプログラムのロジックを単純化し、おそらくより高速に実行されるでしょう。

+0

ファイルごとに6,600万行のレコードがあるので、すべてのレコードを1つのテーブルに入れるのに時間がかかり、さらにテーブルが膨大になります。 –

+1

データベースのヒントでは、膨大なデータを挿入する前にインデックスを作成しないでください。行を挿入するたびに、dbmsは再索引付けし、行数分の時間がかかります。 –

関連する問題