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