org.w3c.util.UUIDとjava.util.UUID
ユニークなIDを生成するための手段として、org.w3c.util.UUID、またJava 5からはjava.util.UUIDがある、というのはいまさらな話。
org.w3c.util.UUIDでは、以下のような文字列が生成される。
<(1)とあるObjectのhashCode(16進)>-<(2)現在時刻(ミリ秒)(16進)>-<(3)IPアドレスのMD5値>
このうち、(1)と(3)はstaticフィールドに保持された値を使用するので、生成されるUUIDで共通。
一方、java.util.UUIDの方はちゃんと追いきれてない。ハイフンで区切られた5個のコンポーネントからなることだけは分かった。JavaDocによると、「ISO/IEC 11578:1996」とかを参照せよ、ということだけど。
で、ふと、org.w3c.util.UUIDのソースを見てみたら、コンストラクタの中で同期用のObjectでsynchronizedしている上に最大10ミリ秒sleepしている。こりゃ、コストがかかりそうだな、ということで(謎)。
まず、org.w3c.util.UUIDの準備。
以下をダウンロード。
- http://dev.w3.org/cvsweb/java/classes/org/w3c/util/UUID.java?sortby=file (Revision 1.2)
- http://dev.w3.org/cvsweb/java/classes/org/w3c/tools/crypt/Md5.java?sortby=file (Revision 1.5)
で、コンパイルとJARファイル生成。SunのJDK(1.5.0_11)を使用。
javac -encoding UTF-8 -d . -g:none org/w3c/tools/crypt/Md5.java org/w3c/util/UUID.java jar cvf uuid.jar org/w3c/util/UUID.class org/w3c/tools/crypt/Md5.class
次に測定用のソース。
public class Main { public static void main(String[] args) { System.out.println("-- 初期化にちょっと時間がかかるようなので一度呼び出しておく。"); test1(1); test2(1); System.out.println("-- 初期化さえされてしまえば、一度の呼び出しは大してコストにならない。"); test1(1); test2(1); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("-- さて、本番‥"); int N = 1000; test1(N); test2(N); } private static void test1(int n) { long start = System.currentTimeMillis(); try { for (int i = 0; i < n; ++i) { org.w3c.util.UUID uuid = new org.w3c.util.UUID(); uuid.toString(); } } finally { long end = System.currentTimeMillis(); System.out.printf(" %-20s: %8d ms\n", "org.w3c.util.UUID", (end - start)); } } private static void test2(int n) { long start = System.currentTimeMillis(); try { for (int i = 0; i < n; ++i) { java.util.UUID uuid = java.util.UUID.randomUUID(); uuid.toString(); } } finally { long end = System.currentTimeMillis(); System.out.printf(" %-20s: %8d ms\n", "java.util.UUID", (end - start)); } } }
で、実行結果。
-- 初期化にちょっと時間がかかるようなので一度呼び出しておく。 org.w3c.util.UUID : 124 ms java.util.UUID : 92 ms -- 初期化さえされてしまえば、一度の呼び出しは大してコストにならない。 org.w3c.util.UUID : 0 ms java.util.UUID : 0 ms -- さて、本番‥ org.w3c.util.UUID : 10187 ms java.util.UUID : 31 ms
まぁ、org.w3c.util.UUIDの方は、生成間隔が10ms以上になるようにsleepしているから、当然といえば当然の結果。
しかし、これだけ差が出るとなると、十分に置き換えの理由になるな。