Java VMでのBuffer速度ベンチマークを測定している方がいたので、Xperia (SO-01B/Android 2.1)でどれくらいの差があるかを大ざっぱにチェックした記録。ソース(javaのみ)
結果の値は全てmsec. (/L:ByteOrder.LITTLE_ENDIAN, /B:ByteOrder.BIG_ENDIAN)
※Xperia (Android 2.1)のByteOrder.nativeOrder() は LITTLE_ENDIAN
▼領域確保 配列長(32768, 131072)のint[]、IntBuffer、ByteBuffer (*4bytes)の確保時間
領域確保(整数型32,768分) | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 | |
int[] | new | 1 | 94 | 1 | 1 | 1 |
IntBuffer | allocateDirect/L | 15 | 4 | 1 | 1 | 2 |
IntBuffer | allocateDirect/B | 287 | 1 | 2 | 1 | 1 |
IntBuffer | allocate/L | 2 | 1 | 91 | 1 | 1 |
IntBuffer | allocate/B | 1 | 1 | 1 | 92 | 1 |
IntBuffer | wrap | 8 | 1 | 1 | 0 | 91 |
ByteBuffer | allocateDirect/L | 1 | 1 | 2 | 2 | 2 |
ByteBuffer | allocateDirect/B | 1 | 1 | 1 | 1 | 1 |
ByteBuffer | allocate/L | 69 | 91 | 1 | 1 | 0 |
ByteBuffer | allocate/B | 1 | 0 | 92 | 1 | 1 |
ByteBuffer | wrap | 0 | 0 | 0 | 91 | 0 |
領域確保(整数型131,072分) | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 | |
int[] | new | 98 | 120 | 93 | 91 | 90 |
IntBuffer | allocateDirect/L | 94 | 96 | 95 | 94 | 144 |
IntBuffer | allocateDirect/B | 3 | 3 | 3 | 3 | 3 |
IntBuffer | allocate/L | 1 | 1 | 0 | 1 | 1 |
IntBuffer | allocate/B | 91 | 91 | 31 | 91 | 91 |
IntBuffer | wrap | 92 | 92 | 90 | 90 | 90 |
ByteBuffer | allocateDirect/L | 96 | 96 | 93 | 94 | 95 |
ByteBuffer | allocateDirect/B | 3 | 3 | 3 | 3 | 3 |
ByteBuffer | allocate/L | 91 | 92 | 90 | 90 | 90 |
ByteBuffer | allocate/B | 91 | 90 | 90 | 90 | 90 |
ByteBuffer | wrap | 92 | 89 | 90 | 91 | 89 |
メモリ確保なのでGCが動いてあまり数値が一定しないが基本的には高速。またwrap自体は0~1msで行われるが表の値は new int[] もしくは new byte[] の時間も含む。
allocateDirect(/L)とallocate/Bが比較的遅め。確保法/バイトオーダーで速さが入れ替わっている。
▼処理速度 (個別に値をセット/一括コピー)
int[] array, IntBuffer ib, ByteBuffer bb の以下の処理時間を測定。
for (int i=0; i<SIZE; i++) array[i]=i; for (int i=0; i<SIZE; i++) ib.put(i); for (int i=0; i<SIZE; i++) bb.putInt(i);
セット速度(整数型32,768分) | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 | 最長を除いた4回の平均* | |
int[] | new | 16 | 15 | 17 | 18 | 17 | 16 |
IntBuffer | allocateDirect/L | 317 | 317 | 345 | 315 | 314 | 316 |
IntBuffer | allocateDirect/B | 444 | 464 | 442 | 371 | 422 | 420 |
IntBuffer | allocate/L | 282 | 284 | 311 | 280 | 281 | 282 |
IntBuffer | allocate/B | 342 | 270 | 759 | 147 | 268 | 257 |
IntBuffer | wrap | 62 | 25 | 85 | 63 | 64 | 54 |
ByteBuffer | allocateDirect/L | 354 | 268 | 264 | 264 | 264 | 265 |
ByteBuffer | allocateDirect/B | 405 | 386 | 246 | 372 | 371 | 344 |
ByteBuffer | allocate/L | 56 | 232 | 229 | 230 | 254 | 187 |
ByteBuffer | allocate/B | 232 | 220 | 216 | 215 | 137 | 197 |
ByteBuffer | wrap | 217 | 229 | 216 | 216 | 217 | 217 |
値のセットはどのBufferも遅い。
System.arraycopy(array, 0, array2, 0, SIZE); ib.put(array); bb.put(bb_src); // bb_srcはByteBuffer.wrap[bytearray2]
コピー速度(整数型131,072分) | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 | 最長を除いた4回の平均* | |
int[] | new | 2 | 3 | 2 | 2 | 2 | 2 |
IntBuffer | allocateDirect/L | 2 | 2 | 2 | 2 | 3 | 2 |
IntBuffer | allocateDirect/B | 9 | 9 | 9 | 9 | 9 | 9 |
IntBuffer | allocate/L | 988 | 824 | 862 | 581 | 835 | 776 |
IntBuffer | allocate/B | 519 | 878 | 270 | 820 | 500 | 527 |
IntBuffer | wrap | 12 | 12 | 13 | 12 | 12 | 12 |
ByteBuffer | allocateDirect/L | 5 | 4 | 5 | 5 | 5 | 5 |
ByteBuffer | allocateDirect/B | 97 | 99 | 94 | 96 | 94 | 95 |
ByteBuffer | allocate/L | 94 | 94 | 95 | 39 | 94 | 80 |
ByteBuffer | allocate/B | 97 | 95 | 94 | 94 | 94 | 94 |
ByteBuffer | wrap | 94 | 109 | 94 | 94 | 95 | 94 |
コピーであれば allocateDirect(/L) が高速。
*裏でGCが動くなど、極端に遅い外れ値を除くため5回中もっとも遅かった値を除いて4回を平均