每个散列表需要处理的输入数据都是不同的,因此没有一个通用的散列表能满足所有的使用场景。在处理性能问题时可以根据自身实际的需求和监视结果检查下面的建议:
1) 创建大小合理的散列表。不过,对于负载因子在0.20以下的散列表,扩展它们不会提高性能。
2) 确保每个散列表中的槽数是一个素数。
3) 在有代表性的数据上测试散列算法,并且度量结果。如果不能使用有代表性的数据,就一定要测试极限数据范围。限制散列函数并只执行一个除法运算(即最后的取模)。
4) 预先考虑冲突,并在可能的地方使用外部拉链法。
下面对2,3,4点做一下说明。
确保每个散列表中的槽数是一个素数。常识告诉我们:当除以一个素数时,会产生最分散的余数。由于我们使用表size对散列结果进行模运算,因此当表size为素数时可以获得最佳的结果。
想要的表达小 | 最接近的素数 | 想要的表大小 | 最接近的素数 | |
---|---|---|---|---|
100 | 97 | 1500 | 1499 | |
250 | 241 | 2000 | 1999 | |
400 | 397 | 4000 | 3989 | |
500 | 499 | 5000 | 4999 | |
750 | 743 | 7500 | 7499 | |
1000 | 997 | 10000 | 9973 |
测试散列算法可以通过打印出链的平均长度,表的利用率及所有链尺寸的列表来分析。如果有许多长链,表就太小;如果仅有几条链很长,数据的某个方面会影响散列函数的结果。
一般来说,散列算法的相对质量不会影响程序的性能,所以应该优先优化其他方面。