Java实现如何提高哈希表的速度

Java实现如何提高哈希表的速度,java,performance,key,hashtable,Java,Performance,Key,Hashtable,我正在实现一个哈希表(根据需求)。它在小输入时工作正常,但不幸的是,在处理大量输入时速度太慢。我尝试了BufferedInputStream,但没有任何区别。基本上我是按照下面的逻辑实现的。有没有办法提高速度?是否存在导致性能不佳的特定功能?或者我们可能需要关闭扫描仪 int [] table = new int [30000];// creat an array as the table Scanner scan = new Scanner (System.in); //use scann

我正在实现一个哈希表(根据需求)。它在小输入时工作正常,但不幸的是,在处理大量输入时速度太慢。我尝试了
BufferedInputStream
,但没有任何区别。基本上我是按照下面的逻辑实现的。有没有办法提高速度?是否存在导致性能不佳的特定功能?或者我们可能需要关闭扫描仪

 int [] table = new int [30000];// creat an array as the table
 Scanner scan = new Scanner (System.in); //use scanner to read the input file. 
 while (scan.hasNextLine()) {
       //read one line at a time, and a sequence of int into an array list called keys  
       // functions used here is string.split(" ");
 }
 hashFuction{
       //use middle-squaring on each elements to the array list keys. 
       // Math.pow() and % 30000, which is the table size, to generate the hash value
       // assign table [hashvalue]= value
 }

首先,你应该知道程序的哪一部分是慢的。优化一切都是一个愚蠢的想法,优化快速部分更糟糕

Math.pow()和%30000,这是表的大小

这是非常错误的

  • 不要将浮点运算用于哈希之类的操作。速度慢,分布不均匀
  • 不要使用既不是2的幂也不是素数的表大小
你没有告诉我们你在散列什么以及为什么。。。假设需要将一对两个整数映射到表中

class IntPair {
    private int x;
    private int y;

    public int hashCode() {
        // the multiplier must be odd for good results
        // its exact value doesn't matter much, but it mustn't equal to your table size; ideally, it should be co-prime
        return 54321 * x + y;
    }

    public boolean equals() {
        do yourself
    }
}

//// Prime table size. The division is slow, but it works slightly better than power of two.

int[] table = new int[30011]; // this is a prime

int hashCodeToIndex(int hashCode) {
    int nonNegative = hashCode & Integer.MAX_VALUE;
    return nonNegative % table.length;
}

//// Power of two table size. No division, faster.

int[] table2 = new int[1<<15]; // this is 2**15, i.e., 32768

int smear(int hashCode) {
    // doing nothing may be good enough, if the hashCode is well distributed
    // otherwise, see e.g., https://github.com/google/guava/blob/c234ed7f015dc90d0380558e663f57c5c445a288/guava/src/com/google/common/collect/Hashing.java#L46
    return hashCode;
}

int hashCodeToIndex(int hashCode) {
    // the "&" cleans all unwanted bits
    return smear(hashCode) & (table2.length - 1);
}

// an alternative, explanation upon request
int hashCodeToIndex2(int hashCode) {
    return smear(hashCode) >>> 17;
}
类IntPair{
私人INTX;
私营企业;
公共int hashCode(){
//乘数必须是奇数才能获得好的结果
//它的精确值无关紧要,但它不能等于您的表大小;理想情况下,它应该是共素数
返回54321*x+y;
}
公共布尔等于(){
做你自己
}
}
////主表大小。除法运算速度慢,但比二次幂运算效果稍好。
int[]表=新int[30011];//这是一个素数
int hashCodeToIndex(int hashCode){
int nonNegative=hashCode&Integer.MAX_值;
返回非负的%table.length;
}
////两张桌子大小的功率。没有分裂,更快。
int[]表2=新int[1>17;
}

首先,你应该知道程序的哪一部分是慢的。优化所有东西都是一个愚蠢的想法,优化快的部分更糟糕

Math.pow()和%30000,这是表的大小

这是非常错误的

  • 千万不要在散列之类的事情上使用浮点运算。它速度慢而且分布不均匀
  • 不要使用既不是2的幂也不是素数的表大小
你没有告诉我们你在散列什么以及为什么…所以让我们假设你需要将一对两个整数映射到表中

class IntPair {
    private int x;
    private int y;

    public int hashCode() {
        // the multiplier must be odd for good results
        // its exact value doesn't matter much, but it mustn't equal to your table size; ideally, it should be co-prime
        return 54321 * x + y;
    }

    public boolean equals() {
        do yourself
    }
}

//// Prime table size. The division is slow, but it works slightly better than power of two.

int[] table = new int[30011]; // this is a prime

int hashCodeToIndex(int hashCode) {
    int nonNegative = hashCode & Integer.MAX_VALUE;
    return nonNegative % table.length;
}

//// Power of two table size. No division, faster.

int[] table2 = new int[1<<15]; // this is 2**15, i.e., 32768

int smear(int hashCode) {
    // doing nothing may be good enough, if the hashCode is well distributed
    // otherwise, see e.g., https://github.com/google/guava/blob/c234ed7f015dc90d0380558e663f57c5c445a288/guava/src/com/google/common/collect/Hashing.java#L46
    return hashCode;
}

int hashCodeToIndex(int hashCode) {
    // the "&" cleans all unwanted bits
    return smear(hashCode) & (table2.length - 1);
}

// an alternative, explanation upon request
int hashCodeToIndex2(int hashCode) {
    return smear(hashCode) >>> 17;
}
类IntPair{
私人INTX;
私营企业;
公共int hashCode(){
//乘数必须是奇数才能获得好的结果
//它的精确值无关紧要,但它不能等于您的表大小;理想情况下,它应该是共素数
返回54321*x+y;
}
公共布尔等于(){
做你自己
}
}
////基本表大小。除法运算速度慢,但比二次幂运算效果稍好。
int[]table=new int[30011];//这是一个素数
int hashCodeToIndex(int hashCode){
int nonNegative=hashCode&Integer.MAX_值;
返回非负的%table.length;
}
////两张桌子大小的力量。无需分割,速度更快。
int[]表2=新int[1>17;
}

首先,你应该知道程序的哪一部分是慢的。优化所有东西都是一个愚蠢的想法,优化快的部分更糟糕

Math.pow()和%30000,这是表的大小

这是非常错误的

  • 千万不要在散列之类的事情上使用浮点运算。它速度慢而且分布不均匀
  • 不要使用既不是2的幂也不是素数的表大小
你没有告诉我们你在散列什么以及为什么…所以让我们假设你需要将一对两个整数映射到表中

class IntPair {
    private int x;
    private int y;

    public int hashCode() {
        // the multiplier must be odd for good results
        // its exact value doesn't matter much, but it mustn't equal to your table size; ideally, it should be co-prime
        return 54321 * x + y;
    }

    public boolean equals() {
        do yourself
    }
}

//// Prime table size. The division is slow, but it works slightly better than power of two.

int[] table = new int[30011]; // this is a prime

int hashCodeToIndex(int hashCode) {
    int nonNegative = hashCode & Integer.MAX_VALUE;
    return nonNegative % table.length;
}

//// Power of two table size. No division, faster.

int[] table2 = new int[1<<15]; // this is 2**15, i.e., 32768

int smear(int hashCode) {
    // doing nothing may be good enough, if the hashCode is well distributed
    // otherwise, see e.g., https://github.com/google/guava/blob/c234ed7f015dc90d0380558e663f57c5c445a288/guava/src/com/google/common/collect/Hashing.java#L46
    return hashCode;
}

int hashCodeToIndex(int hashCode) {
    // the "&" cleans all unwanted bits
    return smear(hashCode) & (table2.length - 1);
}

// an alternative, explanation upon request
int hashCodeToIndex2(int hashCode) {
    return smear(hashCode) >>> 17;
}
类IntPair{
私人INTX;
私营企业;
公共int hashCode(){
//乘数必须是奇数才能获得好的结果
//它的精确值无关紧要,但它不能等于您的表大小;理想情况下,它应该是共素数
返回54321*x+y;
}
公共布尔等于(){
做你自己
}
}
////基本表大小。除法运算速度慢,但比二次幂运算效果稍好。
int[]table=new int[30011];//这是一个素数
int hashCodeToIndex(int hashCode){
int nonNegative=hashCode&Integer.MAX_值;
返回非负的%table.length;
}
////两张桌子大小的力量。无需分割,速度更快。
int[]表2=新int[1>17;
}

首先,你应该知道程序的哪一部分是慢的。优化所有东西都是一个愚蠢的想法,优化快的部分更糟糕

Math.pow()和%30000,这是表的大小

这是非常错误的

  • 千万不要在散列之类的事情上使用浮点运算。它速度慢而且分布不均匀
  • 不要使用既不是2的幂也不是素数的表大小
你没有告诉我们你在散列什么以及为什么…所以让我们假设你需要将一对两个整数映射到表中

class IntPair {
    private int x;
    private int y;

    public int hashCode() {
        // the multiplier must be odd for good results
        // its exact value doesn't matter much, but it mustn't equal to your table size; ideally, it should be co-prime
        return 54321 * x + y;
    }

    public boolean equals() {
        do yourself
    }
}

//// Prime table size. The division is slow, but it works slightly better than power of two.

int[] table = new int[30011]; // this is a prime

int hashCodeToIndex(int hashCode) {
    int nonNegative = hashCode & Integer.MAX_VALUE;
    return nonNegative % table.length;
}

//// Power of two table size. No division, faster.

int[] table2 = new int[1<<15]; // this is 2**15, i.e., 32768

int smear(int hashCode) {
    // doing nothing may be good enough, if the hashCode is well distributed
    // otherwise, see e.g., https://github.com/google/guava/blob/c234ed7f015dc90d0380558e663f57c5c445a288/guava/src/com/google/common/collect/Hashing.java#L46
    return hashCode;
}

int hashCodeToIndex(int hashCode) {
    // the "&" cleans all unwanted bits
    return smear(hashCode) & (table2.length - 1);
}

// an alternative, explanation upon request
int hashCodeToIndex2(int hashCode) {
    return smear(hashCode) >>> 17;
}
类IntPair{
私人INTX;
私营企业;
公共int hashCode(){
//乘数必须是奇数才能获得好的结果
//它的精确值无关紧要,但它不能等于您的表大小;理想情况下,它应该是共素数
返回54321*x+y;
}
公共布尔等于(){
做你自己
}
}
////基本表大小。除法运算速度慢,但比二次幂运算效果稍好。
int[]table=new int[30011];//这是一个素数
int hashCodeToIndex(int hashCode){
int nonNegative=hashCode&Integer.MAX_值;
返回非负的%table.length;
}
////两张桌子大小的力量。无需分割,速度更快。
int[]表2=新int[1>17;
}

您至少需要弄清楚是I/O是瓶颈还是哈希表。如果您使用
哈希表而不是类,您的程序的性能如何?如果是哈希表,我们需要查看它的代码。谢谢。您能推荐一种检查程序哪个部分是瓶颈的方法吗?重写代码使用
HashMap