javaにおけるbase64の性能テスト
標準でなぜかBase64のエンコーダ/デコーダを持たない Java では、複数の実装が存在する。
そこで、性能重視の実装で利用する際、どの実装が一番高速に動作するか調査した。
調査対象
Sun の Java 6 では、「使うべきでない」以下のクラスが標準でインストールされている。
これらのクラスを利用した場合、Java のバージョンや Sun 以外の VM には存在しない可能性があるので、通常、使用すべきではない。
- (1)
com.sun.org.apache.xerces.internal.impl.dv.util.Base64
- (2)
com.sun.org.apache.xml.internal.security.utils.Base64
- (3)
com.sun.xml.internal.messaging.saaj.util.Base64
- (4)
com.sun.xml.internal.ws.util.Base64Util
(エンコーダのみ) - (5)
sun.misc.BASE64Encoder
- (6)
com.sun.xml.internal.messaging.saaj.packaging.mime.util.
BASE64EncoderStream
javamail 1.4.1 の mailapi.jar には Base64 実装が含まれている。
- (7)
com.sun.mail.util.BASE64EncoderStream
Commons Codec に Base64 実装が含まれている。
- (8)
org.apache.commons.codec.binary.Base64
これら8つの実装のエンコード/デコード性能を測定した。
実装方法に関する注意
エンコード方法とデコード方法に記述しているように、実装には最小限の実装である byte[] to byte[] 変換が可能なものと、「VGhlIH…」のように文字列にエンコード/デコードするものに分けられる。
byte[] to byte[] 変換のものはnew String(byte[]) で文字列に変換すれば、利便性の高い実装と結果は同じになるため、byte[] to byte[] 変換の方が、利用できる用途は広がる。
また、速度がほとんど代わらない場合、利用推奨されていない(1)~(6) ではなく、(7)か(8)を使うべきである。
実装番号 | エンコード方法 | デコード方法 |
---|---|---|
(1) | String Base64.encode(byte[]) | byte[] Base64.decode(String) |
(2) | String Base64.encode(byte[]) | byte[] Base64.decode(String) |
(3) | byte[] Base64.encode(byte[]) | byte[] Base64.base64decode(String) |
(4) | String Base64Util.encode(byte[]) | なし |
(5) | String new BASE64Encoder().encode(byte[]) | byte[] new BASE64Decoder().decodeBuffer(String) |
(6) | byte[] BASE64EncoderStream.encode(byte[]) | byte[] BASE64DecoderStream.decode(byte[]) |
(7) | byte[] BASE64EncoderStream.encode(byte[]) | byte[] BASE64DecoderStream.decode(byte[]) |
(8) | byte[] Base64.encodeBase64(byte[]) | byte[] Base64.decodeBase64(byte[]) |
測定方法
次のようなプログラムを作成。(1 の エンコードの例)
String original = "The quick brown fox jumps over the lazy dog"; byte[] originalData = original.getBytes(); long t = System.currentTimeMillis(); for (int i = 0; i < 10000 * 1000; i++) { Base64.encode(originalData); } long t2 = System.currentTimeMillis(); System.out.println(t2 - t);
なお、与える文字列により実行時間が変わることが考えられるが、そこまで測定はしていない。
測定結果
実装番号 | エンコード時間 | デコード時間 |
---|---|---|
(1) | 2562 | 5047 |
(2) | 2656 | 10594 |
(3) | 1656 | 10828 |
(4) | 9500 | なし |
(5) | 79297 | 29985 |
(6) | 1688 | 1844 |
(7) | 1531 | 1781 |
(8) | 2172 | 4156 |
(7) javamail の実装が最も高速に動作した。
javamail の base64 を使ったサンプル
package jp.trasis.samples.base64; import com.sun.mail.util.BASE64DecoderStream; import com.sun.mail.util.BASE64EncoderStream; public class Sample7 { public static void main(String[] args) { String original = "The quick brown fox jumps over the lazy dog"; byte[] encData = BASE64EncoderStream.encode(original.getBytes()); String enc = new String(encData); System.out.println(enc); byte[] data = BASE64DecoderStream.decode(encData); String s2 = new String(data); System.out.println(s2); } }