下面是在 beta 127 中运行的测试。
请记住,这个测试是不现实的,超出了我能想象到的任何最坏情况。我的目标是让那些恶语相传的人安静下来,而事实却没有事实来支持他们的批评。
场景:
- 对
java.util.UUID.randomUUID()
的一百万次调用的紧密循环
- 一个测试,仅凭这一点。(无争用)
- 一个具有争用的测试,其中其他 2 个线程处于紧密循环中,进行 1000 万次调用。
- Java 8 beta 127
- java 版本 “1.8.0”
- Java(TM) SE Runtime Environment (build 1.8.0-b127)
- Java HotSpot(TM) 64 位服务器虚拟机(内部版本 25.0-b69,混合模式)
- 从 Netbeans 7.4 IDE 运行
- 在虚拟机内执行
-
Mac mini (2012 年末)
无争用
在一个线程中运行一个循环,因此不会争用同步的方法/类。
// Warm the random generator.
java.util.UUID uuid;
uuid = java.util.UUID.randomUUID();
long stop = 0;
long start = System.nanoTime();
int loops = 1000000; // One million.
for ( int i = 0; i < loops; i++ ) {
uuid = java.util.UUID.randomUUID();
}
stop = System.nanoTime();
long elapsed = ( stop - start );
System.out.println( "UUIDs: " + loops );
System.out.println( "Nanos: " + elapsed );
System.out.println( "Nanos per uuid: " + ( elapsed / loops ) + " ( micros per: " + ( elapsed / loops / 1000 ) + " )" );
结果
每个 UUID 大约 2 微秒。
与争用
与上面类似,但是在执行一百万个调用的循环时,我们还有另外两个线程在运行,每个线程进行一千万次调用。
// Warm the random generator.
java.util.UUID uuid;
uuid = java.util.UUID.randomUUID();
int pass = 10_000_000 ; // Ten million.
MyThread t1 = new MyThread( pass );
MyThread t2 = new MyThread( pass );
t1.start();
t2.start();
t3.start();
long stop = 0;
long start = System.nanoTime();
int loops = 1_000_000 ; // One million.
for ( int i = 0; i < loops; i++ ) {
uuid = java.util.UUID.randomUUID();
}
stop = System.nanoTime();
long elapsed = ( stop - start );
System.out.println( "UUIDs: " + loops );
System.out.println( "Nanos: " + elapsed );
System.out.println( "Nanos per uuid: " + ( elapsed / loops ) + " ( micros per: " + ( elapsed / loops / 1000 ) + " )" );
定义每个线程的类...
class MyThread extends Thread {
private int loops;
public MyThread( int loops ) {
this.loops = loops;
}
@Override
public void run() {
java.util.UUID uuid;
for ( int i = 0; i < this.loops; i++ ) {
uuid = java.util.UUID.randomUUID();
}
}
}
结果
每个 UUID 大约 20 微秒。
运行次数为每 UUID 14、20、20、23 和 24 微秒(不按此顺序)。因此,在极端的争论下,情况只差了大约10倍,在我所知道的任何现实世界中,20微秒是可以接受的。