Java 更快的hashCode()替代方案?

Java 更快的hashCode()替代方案?,java,Java,有没有办法让hashCode()更快?当然,我知道这可能会导致更多的碰撞,但我同意这种权衡 java有没有办法“获取对象的内存地址,比如C++?”/P> > >编辑::我理解HASCODE()是快的。我的目标是创建一个散列函数,它和一些C++散列函数一样快。 我将散列的项目类型未知 有没有办法让hashCode()更快 是的,有很多种方法,但这取决于你在散列什么 注意:内置的Object.hashCode()大约需要40纳秒 java有没有办法“获取对象的内存地址,比如C++?”/P> 是

有没有办法让hashCode()更快?当然,我知道这可能会导致更多的碰撞,但我同意这种权衡

java有没有办法“获取对象的内存地址,比如C++?”/P> <> > >编辑::我理解HASCODE()是快的。我的目标是创建一个散列函数,它和一些C++散列函数一样快。 我将散列的项目类型未知

有没有办法让hashCode()更快

是的,有很多种方法,但这取决于你在散列什么

注意:内置的Object.hashCode()大约需要40纳秒

java有没有办法“获取对象的内存地址,比如C++?”/P> 是的,您可以使用“不安全”来执行此操作,但是这不是一个好主意,因为对象的地址随时都可能更改,使其无法用作哈希


此程序触发Object.hashCode()的重新计算

注意:这是一个非常粗糙的方法,可能无法在所有JVM或未来的JVM上使用。它仅用于教育目的。

public class HashCodePerf {
    static int keep;

    public static void main(String[] args) {
        Object o = new Object();
        int runs = 20_000_000;
        for (int t = 0; t < 5; t++) {
            long start = System.nanoTime();
            for (int i = 0; i < runs; i++) {
                UNSAFE.putInt(o, 1L, 0); // reset the memory which stores the hashCode
                keep = o.hashCode(); // compute a new hashCode
            }
            long time = System.nanoTime() - start;
            System.out.printf("Object.hashCode takes %,d ns on average%n", time / runs);
        }
    }

    static final Unsafe UNSAFE;

    static {
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            UNSAFE = (Unsafe) theUnsafe.get(null);
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

创建一个非常简单的散列,将其添加到计数器

static int keep, keep2;
static int counter;

public static void main(String[] args) {
    Object o = new Object();
    Object o2 = new Object();
    int runs = 100_000_000;
    for (int t = 0; t < 5; t++) {
        long start = System.nanoTime();
        for (int i = 0; i < runs; i+=2) {
            UNSAFE.putOrderedInt(o, 1L, (counter += 0x5bc80bad) & 0x7FFFFFFF);
            UNSAFE.putOrderedInt(o2, 1L, (counter += 0x5bc80bad) & 0x7FFFFFFF);
            keep = o.hashCode(); // reload the hashCode
            keep2 = o2.hashCode(); // reload the hashCode
        }
        long time = System.nanoTime() - start;
        System.out.printf("Object.hashCode takes %,d ns on average%n", time / runs);
    }
}
注意:通常一个对象的地址会改变,但它的哈希代码不会改变。在本例中,对象的哈希代码不断变化,但地址相同

有没有办法让hashCode()更快

是的,有很多种方法,但这取决于你在散列什么

注意:内置的Object.hashCode()大约需要40纳秒

java有没有办法“获取对象的内存地址,比如C++?”/P> 是的,您可以使用“不安全”来执行此操作,但是这不是一个好主意,因为对象的地址随时都可能更改,使其无法用作哈希


此程序触发Object.hashCode()的重新计算

注意:这是一个非常粗糙的方法,可能无法在所有JVM或未来的JVM上使用。它仅用于教育目的。

public class HashCodePerf {
    static int keep;

    public static void main(String[] args) {
        Object o = new Object();
        int runs = 20_000_000;
        for (int t = 0; t < 5; t++) {
            long start = System.nanoTime();
            for (int i = 0; i < runs; i++) {
                UNSAFE.putInt(o, 1L, 0); // reset the memory which stores the hashCode
                keep = o.hashCode(); // compute a new hashCode
            }
            long time = System.nanoTime() - start;
            System.out.printf("Object.hashCode takes %,d ns on average%n", time / runs);
        }
    }

    static final Unsafe UNSAFE;

    static {
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            UNSAFE = (Unsafe) theUnsafe.get(null);
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

创建一个非常简单的散列,将其添加到计数器

static int keep, keep2;
static int counter;

public static void main(String[] args) {
    Object o = new Object();
    Object o2 = new Object();
    int runs = 100_000_000;
    for (int t = 0; t < 5; t++) {
        long start = System.nanoTime();
        for (int i = 0; i < runs; i+=2) {
            UNSAFE.putOrderedInt(o, 1L, (counter += 0x5bc80bad) & 0x7FFFFFFF);
            UNSAFE.putOrderedInt(o2, 1L, (counter += 0x5bc80bad) & 0x7FFFFFFF);
            keep = o.hashCode(); // reload the hashCode
            keep2 = o2.hashCode(); // reload the hashCode
        }
        long time = System.nanoTime() - start;
        System.out.printf("Object.hashCode takes %,d ns on average%n", time / runs);
    }
}
注意:通常一个对象的地址会改变,但它的hashCode不会改变。在这种情况下,我们有hashCode改变但地址相同的对象

有没有办法让hashCode()更快?当然我知道这可能会导致更多的冲突,但我同意这种折衷

这个问题的最佳答案是:

public int hashCode() {
     return 0;
}
这对于任何
对象来说都是正确的,它的速度是最快的,并且它将为您提供大量的碰撞,您可以接受

有没有办法让hashCode()更快?当然我知道这可能会导致更多的冲突,但我同意这种折衷

这个问题的最佳答案是:

public int hashCode() {
     return 0;
}

这对于任何
对象来说都是正确的,它的速度是最快的,并且它将为您提供大量的碰撞,您对此没有意见。

如果您想要类似于对象地址的内容,您可以使用:

System.identityHashCode(obj);
如果多次调用hascode方法,还可以缓存/预计算结果(假设对象是不可变的,或者至少其hashcode在构造后不会更改)


如果需要与对象地址类似的内容,可以使用:

System.identityHashCode(obj);
如果多次调用hascode方法,还可以缓存/预计算结果(假设对象是不可变的,或者至少其hashcode在构造后不会更改)


你能提供更多的信息,我可以写我自己的hash码吗?对象。hash CODER()与一些C++散列函数相比慢了。任何方法都能使它像C++一样快吗?@ Mth000可以重写哈希科德()。您可以使它与C++一样快,但如何做取决于您散列的数据。没有一种大小适合的方法。当创建对象时,哈希代码是否自动计算,无论我是否调用该函数。@ Mth000,它是第一次被调用,即懒惰。参见上面的示例,在这里我把时间缩短到< COD。En> 4 NS平均值。请提供更多关于如何编写自己的HASCODE的信息?对象。hash CODER()与某些C++散列函数相比慢。任何方式都能使它与C++(@ Mth000)一样快,您可以重写哈希代码()。您可以使它与C++一样快,但如何做取决于您散列的数据。没有一种大小适合的方法。当创建对象时,哈希代码是否自动计算,无论我是否调用该函数。@ Mth000,它是第一次被调用,即懒惰。参见上面的示例,在这里我把时间缩短到< COD。e> 平均为4 ns
。另请参阅:根据您的用例,您还可以预计算或缓存哈希代码值,以便在进行大量哈希运算时将成本降至最低。@Andrew Regan:谢谢,缓存是一个好主意。另请参阅:根据您的用例,您还可以预计算或缓存哈希代码值,以便在有散列的成本最小化了。@Andrew Regan:谢谢,缓存是个好主意。我的目标是在碰撞和速度之间找到平衡。我的目标是在碰撞和速度之间找到平衡。。。?