byte[] -> String 変換のパフォーマンス、とAndroidでCharsetDecoder#decode(ByteBuffer in).toString()が遅い件
Android上でMessagePackのベンチマークコードを動かしつつprofile取ってみたら、msgpack-java/src/main/java/org/msgpack/unpacker/StringAccept.java at master · msgpack/msgpack-java · GitHub辺り(CharsetDecoder#decode(ByteBuffer in).toString())でほとんどの時間が掛かっているなぁ、という感じ。
で、そもそも new String(byte[] byte, String charsetName) と CharsetDecoder#decode(ByteBuffer in).toString() でどれくらい性能があるのか気になったので計測してみた。確か、new String(...) の内部で CharsetDecoder#decode() してるというのは以前調べたことがあったので、今回はどの位違ってくるのか?という点に着目。
public static void main(String[] args) throws IOException { String src = "あいうえおアイウエオアイウエオaiueoAIUEO"; byte[] raw = src.getBytes(); ByteBuffer byteBuffer = ByteBuffer.wrap(raw); Charset cs = Charset.forName("UTF-8"); int until = 10000000; long start = System.currentTimeMillis(); for (int i = 0; i < until; i++) { cs.newDecoder().decode(byteBuffer).toString(); } System.out.println("CharsetDecoder.decode(): " + (System.currentTimeMillis() - start)); start = System.currentTimeMillis(); for (int i = 0; i < until; i++) { new String(raw, "UTF-8"); } System.out.println("String(byte[]): " + (System.currentTimeMillis() - start)); }
こんなのを書いて動かして見たところ...
CharsetDecoder.decode(): 720 String(byte[]): 2367
ざっと3倍位new String(byte[] byte, String charsetName)のほうが遅かった。OpenJDK 1.6でも大体同じ。
- Android OS 4.2
I/XXXX (28542): CharsetDecoder.decode(): 4366 I/XXXX (28542): String(byte[]): 1471
同等のコードをDalvik VM上で動かしたら(ループの回数は1/100に減らした)、結果が逆転した。ちょうど三倍程度、CharsetDecoder.decodeの方が遅くなった。