Android付属のTimeクラスを使って,GPXファイルに含まれる日時文字列(time要素)の解析を高速化した話.
android.text.format.Timeの利用
地図ロイドにGPXファイルの読み込み処理を実装してパフォーマンスチューニングしていると,
GPXファイルに含まれているtime要素の日時文字列
<time>2009-11-03T05:38:46Z</time>
を日時として解析する処理がボトルネックになっていることがわかりました.
(
GPXの仕様 では,time要素のtimezoneはUTCに決められています)
ここは従来はSimpleDateFormat#parse()を使っていたのですが,AndroidのAPIを漁っていて見つけた
Timeクラス のparse3339()メソッドを使うことで,劇的に高速化できました.
以下のテストコードで,2つのメソッドは同じ処理をおこなっています.
- getParsedTime1 - SimpleDateFormat#parse() 方式
- getParsedTime2 - Time#parse3339() 方式
実行結果 (HT-03A.数回実行した平均)
方式 | 所要時間 |
SimpleDateFormat#parse() | 29秒 |
Time#parse3339() | 3秒 |
速いですねぇ...
public
static
class
TrkPoint {
String time;
private
SimpleDateFormat sdf;
private
Time androTime;
public
TrkPoint() {
sdf = new
SimpleDateFormat("yyyy-MM-dd'T'
HH:mm:ss'Z'
");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"
));
androTime = new
Time();
androTime.switchTimezone("UTC"
);
}
// SimpleDateFormatを使う版
public
long
getParsedTime1() {
try
{
return
sdf.parse(time).getTime();
} catch
(ParseException ex) {
throw
new
RuntimeException(ex);
}
}
// Android付属Timeを使う版
public
long
getParsedTime2() {
androTime.parse3339(time);
return
androTime.normalize(false
);
}
}
// テストデータの準備
SimpleDateFormat sdf = new
SimpleDateFormat("yyyy-MM-dd'T'
HH:mm:ss'Z'
");
String[] timeList = new
String[5000];
for
(int
i = 0; i < timeList.length; i++) {
timeList[i] = sdf.format(new
Date(System.currentTimeMillis() + i*1000));
}
List<Long> dlist = new
ArrayList<Long>(timeList.length);
TrkPoint point = new
TrkPoint();
// パース処理実行
long
t1 = System.currentTimeMillis();
for
(String t: timeList) {
point.time = t;
long
l = point.getParsedTime1();
// long l = point.getParsedTime2();
dlist.add(l);
}
// 終了
long
t2 = System.currentTimeMillis();
log("elapsed="
+ (float
)(t2-t1)/1000);