2012年12月23日日曜日

Javaでbyte配列を16進文字列にする時の速度比較

Javaでプログラミングしていると、byte配列(byte[])を16進の文字列に変換したいことは多い。
例えば、MD5やSHA-1,SHA-512などハッシュ値に置き換えるときや、バイナリデータのバンプなどがある。
上記のコードは、様々なところで紹介されているが、いったいどの方法が速いのだろうか?

VM環境は、Windows 7 + Oracle JRE 7 という、とても一般的な環境。
試したパターンは、10通り。そのうち比較として面白いものを4つ選んだ。
どのパターンも前提として、by:byte[]、sb:StringBuilder、とする。

//パターン1
for (byte b : by)
 sb.append(String.format("%02x", b));
//パターン2
for (int b : by) {
 sb.append(Integer.toHexString(b >> 4 & 0xF));
 sb.append(Integer.toHexString(b & 0xF));
}
//パターン3
for (int b : by) {
 int b2 = b & 0xff;
 if (b2 < 16) sb.append("0");
 sb.append(Integer.toHexString(b2));
}
//パターン4
for (int b : by) {
 sb.append(Character.forDigit(b >> 4 & 0xF, 16));
 sb.append(Character.forDigit(b & 0xF, 16));
}
実行結果は、以下のとおりである。
パターン実行時間
パターン147817ms
パターン24313ms
パターン32310ms
パターン4588ms
パターン1は、フォーマット文字列の解析があるので、明らかに遅くなるのは間違いない。ほぼ予想通りであるといえる。 パターン2とパターン3からいえることは、これらの処理の中でInteger.toHexString()が一番時間がかかるといえる。 結果としては、パターン4が明らかに速い。理由はOpenJDKのソースを見ると明らかだ。 Integer.toHexStringは複数の桁を検査し、それをnew String()している。 Character.forDigitは1桁目のみ検査し、それをcharで返している。 charはintと同様クラスではないので速いのだろう。Stringはクラスなので、生成にコストがかかる。 今回の調査でわかったことは、Stringの生成は意外とコストが大きく、StringBuilder.append()は速いということだった。 Stringの生成が遅いので作られたものがStringBuilderという点からしても当たり前か。

Enterprise JavaBeans 3.1 第6版

2012年4月28日土曜日

ついに本格始動

IT企業に転職して、1ヶ月たちました。公務員時代にはできなかったことをいろいろやるのが今年の目標です。

公務員時代には、公務員倫理規程で兼業禁止になっており、アプリの販売やサービスに課金ができませんでした。そのため、アプリやサービスの開発運営はすべて広告収入のみで賄っていたため、ほとんどが赤字事業です。
4月から民間企業に移り、アプリの販売やサービスに課金を行えるようになったので、いろいろなサービスを本格的に始めて月980円のVPSが借りられるくらいの収入が入るまで、成長させたいと考えています。

そこで、「日本語フルキーボード For Tablet」の新機能と、現在行っている事業を紹介したいと思います。

まず、「日本語フルキーボード For Tablet」の新機能は、広告非表示有料オプションの開始です。従来から要望されていた機能です。
現在は単純に広告が非表示になるだけの広告非表示オプションのみですが、今後いろんなオプションを備えて、すべて買うとATOK以上の価格にしようと企てています。

次に、現在行っている事業ですが、Webサービスが1サイトと、Androidアプリ3本のみです。
2ch to RSS(広告)
連続バーコードリーダー(広告)
Picasa アップローダー(広告)
日本語フルキーボード For Tablet(広告+販売)
現在、人件費以外の経費は0円なので、広告収入がそのまま人件費になりますが、時給換算で100円にも満たないので何とかしようと思います。