2

シーン:

  • 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;
    }
  }
}
4

1 に答える 1