我有一个长度为614 125的对象数组。 重点是通过获取每个字节值的模数85来从3个字节的数字中获取索引。
它是一个很大的阵列,但FAR低于允许的极限,但它速度极慢,尽管有直接索引访问(我实际上从不迭代数组)。
问题在于我使用的是散乱值(3个字节),这是我事先无法知道的,因此我无法预测该值,也不能将其缩小。我的想法似乎很聪明,但阵列太大了,这让我的游戏慢了两倍。
这种情况有替代方案吗?请注意,我已经尝试过HashMap,但它更慢,因为我的哈希值太远了。
我试图找到一种不从一开始就分配大型数组的方法,而是动态添加新对象。使用我的Node对象" next"和"之前"会解决问题并且会很快排序,但是我无法找到一种方法来找到没有O(N / 2)顺序的散列,这太长了(我想要O(1))。
以下是代码,如果有任何用处:
public class HashMap {
public static final int ARRAY_SIZE = 614125;
// This value represents 255/3 (max byte value)=> hash is 3 bytes long:
// First byte%85 gives us the first index, same for second and third.
private static final int MODULO = 85;
private static final int FIRST_MULTIPLIER = 7225;
private static final int SECOND_MULTIPLIER = 85;
private Node[] mHashMap;
private int index1, index2, index3;
public HashMap() {
mHashMap = new Node[ARRAY_SIZE];
}
public void put(int hash, int value) {
index1 = (hash & 0xFF) % MODULO;
index2 = ((hash >> 8) & 0xFF) % MODULO;
index3 = ((hash >> 16) & 0xFF) % MODULO;
int index = index1 * FIRST_MULTIPLIER + index2 * SECOND_MULTIPLIER + index3;
Node node = mHashMap[index];
if (node == null) {
mHashMap[index] = new Node(value);
} else {
node.addValue(value);
}
}
public Node get(int hash) {
index1 = (hash & 0xFF) % MODULO;
index2 = ((hash >> 8) & 0xFF) % MODULO;
index3 = ((hash >> 16) & 0xFF) % MODULO;
int index = index1 * FIRST_MULTIPLIER + index2 * SECOND_MULTIPLIER + index3;
return mHashMap[index];
}
}
public class Node {
private Node mNext;
private int mValue;
public Node(int value) {
mValue = value;
mNext = null;
}
public void setNext(Node next) {
mNext = next;
}
public boolean hasNext() {
return mNext != null;
}
public Node next() {
return mNext;
}
public int getValue() {
return mValue;
}
public void addValue(int value) {
mValue += value;
}
}
答案 0 :(得分:0)
我试图找到一种不从一开始就分配大型数组的方法,而是动态添加新对象。
为什么呢? IIUYC您不需要最小化内存消耗。使用较少的内存可能会导致速度增加,但我认为它不适用于此。
罪魁祸首很可能是你的哈希计算速度很慢。多次执行%
非常昂贵,此处不需要。如果要将int
映射到数组索引,可以使用单个模数(当数组大小为素数时很好)或根本没有慢速操作(当数组大小是2的幂。)
我建议像
这样的东西private static final int LOG_ARRAY_SIZE = 19;
private static final int ARRAY_SIZE = 1 << LOG_ARRAY_SIZE;
private int toIndex(int x) {
return (x * 0xcc9e2d51) >>> (32-LOG_ARRAY_SIZE);
}
public void put(int hash, int value) {
index = toIndex(hash);
Node node = mHashMap[index];
if (node == null) {
mHashMap[index] = new Node(value);
} else {
node.addValue(value);
}
}
public Node get(int hash) {
index = toIndex(hash);
return mHashMap[index];
}