我正在寻找一个高性能的数据结构,其行为类似于一个集合,其中元素将始终是一个int数组。数据结构只需要实现这个接口:
trait SetX {
def size:Int
def add(element:Array[Int])
def toArray:Array[Array[Int]]
}
该集合不应包含重复项,这可以使用Arrays.equals(int [] a,int [] a2)来实现 - 即数组的值不能相同。
在创建它之前,我大致了解将会有多少元素,但需要调整大小的行为,以防万一有多于最初的想法。元素将始终具有相同的长度,我知道创建时的内容。
当然我可以使用Java HashSet(当然包装数组),但这是在紧密循环中使用而且速度太慢。我看过Trove并且运行良好(通过使用数组但提供了TObjectHashingStrategy)但我希望由于我的要求如此具体,所以可能有更快/更有效的方法来实现这一点。
有没有人遇到这个或者知道如何才能做到这一点?
上面的特性是Scala,但我对Java库或代码非常满意。
我应该说出我在做什么。我基本上是在一个紧凑的循环中生成大量的int数组,在它的最后我只想看到独特的。我永远不必从集合或其他任何东西中删除元素。只需在集合中添加大量的int数组,最后就可以得到唯一的数组。
答案 0 :(得分:1)
看看prefix trees。您可以在阵列生成期间立即遵循树结构。如果生成的数组已存在于集合中,那么在生成结束时您将得到答案。前缀树比普通的哈希集消耗更少的内存。
如果你正在生成阵列并且其等效性的可能性很小,我怀疑你只是从非常有限的范围内获取数字。它也会简化前缀树的实现。
我确信正确的实现比使用任何set实现来保持实体数组更快。
此解决方案的缺点是您需要自己实现数据结构,因为它将深深地与代码逻辑集成。
答案 1 :(得分:0)
不知道有多少数据,或者你是否正在做更多的读取而不是写:
您应该尝试(即基准测试)数组数组或特殊包装数组的数组(即具有数组缓存哈希码和数组的复合对象)的天真情况。通常在小数据集上没有多少跳过数组(例如,Enum的HashMap实际上比循环更慢)。
如果你有大量的数据且愿意做出妥协,你可能会考虑bloom filter,但听起来你没有太多数据。
答案 2 :(得分:0)
如果你想要高性能,那就写下自己的:
将其命名为ArraySetInt。
通常将集合实现为树或哈希表。
如果你想要一个基于数组的集合,这会减慢添加,可能会删除,但会加速迭代,低内存使用。等
首先看一下ArrayList的实现方式。 删除对象并用原始int替换它。
然后将add()重命名为put()并通过插入将其更改为排序类型。使用System.arraycopy()进行插入。使用Arrays.binsearch()来查找插入位置以及元素是否已经存在于一个步骤中。
答案 3 :(得分:0)
我会选择一个经典的解决方案,通过提供更快equals
和hashCode
的类来包装数组。 hashCode
可以简单地缓存,equals
可以使用它来快速拒绝不同的数组。
我会避免Arrays.hashCode
因为它使用了一个愚蠢的乘数(31),这可能会导致不必要的碰撞。对于一个非常快的equals
,你可以使用密码学,并说两个数组是等于的,当且仅当它们的SHA-1相等时(你是第一个发现碰撞的数据:D)。 / p>
ArrayWrapper相当简单,应该比使用TObjectHashingStrategy
更快,因为它永远不必查看数据本身(更少的缓存未命中),并且它具有最快和最好的hashCode
和equals
。
你也可以寻找一些CompactHashSet实现,因为它可以更快,因为更好的内存局部性。