シーン:
- System.identityHashCode を多用する XStream を使用しています。
- IBM Java 1.5 から Oracle Java 7 に移行しました
問題:
パフォーマンスの問題があり、System.identityHashCode が問題である可能性があることを確認しました。
質問:
- 新しい Java (および IBM から Oracle への変更) でこのパフォーマンスの低下が見られる理由について、何か良い説明はありますか?
- このボトルネックを回避するにはどうすればよいですか?
以下は私のベンチマークです(すべて同じハードウェアで実行されます):
32 bit Oracle Java 7
System.identityHashCode: 517669471 - 51ns
Object.hashCode: 491220730 - 49ns
64 bit Oracle Java 7:
System.identityHashCode: 353134647 - 35ns
Object.hashCode: 339331774 - 33ns
IBM Java 1.5
System.identityHashCode: 19241979 - 1ns
Object.hashCode: 89621026 - 8ns
Bechmark プログラムのソースは次のとおりです。
import java.util.*;
public class HashCodeTest
{
static int ITS = 10000000;
static Object O = new Object();
public static void main(String[] args)
{
TreeSet<Integer> large = new TreeSet<Integer>();
Random ran = new Random();
for (int i=0; i<10000; i++) {
large.add(ran.nextInt());
}
testIdentityHashCode(large);
testHashCode(large);
testIdentityHashCode(large);
testHashCode(large);
}
protected static void testIdentityHashCode(TreeSet<Integer> large)
{
long start = System.nanoTime();
for (int i=0; i<ITS; i++) {
Object o = new Container(large);
System.identityHashCode(o);
}
long end = System.nanoTime();
System.out.println("System.identityHashCode: " + (end-start) + " - " + (end-start)/ITS + "ns");
}
protected static void testHashCode(TreeSet<Integer> large)
{
long start = System.nanoTime();
for (int i=0; i<ITS; i++) {
Object o = new Container(large);
o.hashCode();
}
long end = System.nanoTime();
System.out.println("Object.hashCode: " + (end-start) + " - " + (end-start)/ITS + "ns");
}
private static class Container {
private final Object o;
public Container(Object o)
{
this.o = o;
}
}
}