2009年07月17日

高速化

引き続き、解析プログラムを手直し中です。


今回は当初は考慮していなかった速度面をちょっと改善しました。
javaで作っているので、もともと速度にこだわるつもりもないんですが
あまりにも遅かったので・・・

で、XMLパーサーが重いのは分かっていたので
StringTokenizerを使った独自処理に置き換えたところ
予想以上に速くなりました。

GZIPInputStreamが以外に高速な事も分かりました。

■和了・放銃の集計処理時間■
処理件数:1178
XMLパースの処理時間:4522 → 581
データ解析の処理時間:1673 → 1176
カウント処理時間:672 → 701
トータル:6867 → 2458

置き換えの過程で
java.lang.String.split()がとてつもなく遅い事が判明しました。
簡単なXMLを大量にパースする時の処理速度はこんな感じ↓

DocumentBuilder = split >>>>>>> StringTokenizer

StringTokenizerは7倍くらい高速です。
(なので、「データ解析の処理」も、split→tokenizerで若干速くなりました。)
まぁ、正規表現を使っているので何となく予想はしていましたが、
XMLパーサーと同等の重さだとは思いませんでした。
今後のjavaプログラミングでとても参考になります。

ちなみに、GZIPInputStreamの解凍処理時間は今回の件数で500ms。 案外軽いんだなという印象です。

速度だけ考えればC++でもっと高速に作って気持ちよくなりたいところですが、 何の意味もないので今回はここまで。

ちなみに、tokenizerを使った高速splitやGZIPInputStreamの処理はこんな感じです。

/**
* 標準の split が非常に遅いので StringTokenizer を使ってみた
*/
public class Splitter {
public static String[] split(String str, String delimiter) {
  StringTokenizer tokenizer = new StringTokenizer(str, delimiter);
  String[] resultStr = new String[tokenizer.countTokens()];

  int i = 0;
  while (tokenizer.hasMoreTokens()) {
    resultStr[i++] = tokenizer.nextToken();
  }
  return resultStr;
}
}

/**
* GZIPInputStreamでgzファイルをロードする処理
*/
String body = null;
InputStream is = null;
try {
  is = new GZIPInputStream(new FileInputStream(file));
  BufferedReader br = new BufferedReader(new InputStreamReader(is));

  // ファイル読み込み
  body = br.readLine();

  is.close();
  br.close();
}
catch (Exception ex) {}
posted by idaten! at 13:00| Comment(0) | TrackBack(0) | プログラミング
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/30585038
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック