今回は当初は考慮していなかった速度面をちょっと改善しました。
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) {}