替代Java中的大数组?
我有一个长度为614125的对象数组。 关键是通过获取每个字节值的模85,从3字节数中获取索引 这是一个很大的数组,但远低于允许的限制,但是速度非常慢,尽管有直接的索引访问(实际上我从来没有迭代过数组) 问题是我使用的散列值(3字节)事先无法知道,因此我无法预测该值,也无法将其缩小。我的想法似乎很聪明,但阵列太大,使我的游戏速度慢了两倍 除了这种情况,还有别的选择吗?请注意,我尝试了HashMap,但速度更慢,因为我的哈希值相距太远 我试图找到一种方法,从一开始就不分配一个巨大的数组,而是动态地添加新对象。使用带有“next”和“previous”的Node对象可以解决这个问题,并且可以使排序非常快,但是如果没有O(N/2)顺序,我无法找到查找哈希的方法,因为它太长了(我想要O(1)) 以下是代码(如果有任何用途): 哈希图 节点 我试图找到一种方法,从一开始就不分配一个巨大的数组,而是动态地添加新对象 为什么??IIUYC您不需要最小化内存消耗。使用更少的内存可能会提高速度,但我认为这不适用于这里 罪魁祸首很可能是您非常缓慢的哈希计算。多次执行替代Java中的大数组?,java,arrays,performance,data-structures,Java,Arrays,Performance,Data Structures,我有一个长度为614125的对象数组。 关键是通过获取每个字节值的模85,从3字节数中获取索引 这是一个很大的数组,但远低于允许的限制,但是速度非常慢,尽管有直接的索引访问(实际上我从来没有迭代过数组) 问题是我使用的散列值(3字节)事先无法知道,因此我无法预测该值,也无法将其缩小。我的想法似乎很聪明,但阵列太大,使我的游戏速度慢了两倍 除了这种情况,还有别的选择吗?请注意,我尝试了HashMap,但速度更慢,因为我的哈希值相距太远 我试图找到一种方法,从一开始就不分配一个巨大的数组,而是动态地
%
非常昂贵,此处不需要。如果要将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];
}
private static final int LOG\u ARRAY\u SIZE=19;
私有静态最终整数数组大小=1>>(32-LOG数组大小);
}
公共void put(int散列,int值){
索引=toIndex(散列);
Node Node=mHashMap[索引];
if(node==null){
mHashMap[索引]=新节点(值);
}否则{
node.addValue(value);
}
}
公共节点get(int散列){
索引=toIndex(散列);
返回mHashMap[索引];
}
您分析过代码了吗?哪种方法会让你慢下来?您可以在O(1)中运行方法,这样看起来就不会成为瓶颈…只是一个提示:永远不要将您自己编写的类命名为与标准Java库中的类相同的名称:这样可以省去很多麻烦。@assylias是的,这只是由于数组的大小。使用数组(比如85)执行完全相同的代码(因此仅使用index1)非常快。但是一旦尺寸增大,它就会变得非常慢。大型阵列本身并不慢。无论索引有多大,访问数组元素几乎是瞬时的。您没有任何代码可以逐步遍历数组的所有元素。如果一个大的数组太大以至于需要大量的内存交换,那么它可能会导致速度变慢,但我认为数组不会太大而导致问题,除非您运行在一台内存非常有限的非常旧的计算机上。我怀疑您的性能问题在其他地方。@zuokuok对于较大的数组,您的代码不应该较慢。问题可能在其他地方(可能是另一个类)。分析您的代码并检查花费在GC上的时间。
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;
}
}
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];
}