Trasis Inc.

渋谷拠点のシステム開発会社

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);
}
}