单线程 Contains(Point(x,y)) 功能最快的 Java 集合是什么?
在我的应用程序中,我需要检查 2D 坐标 (x,y) 的集合,以查看给定坐标是否在集合中,它需要尽可能快,并且只能从一个线程访问。 (用于碰撞检查)
有人可以推我到正确的方向吗?
In my application I need to check a collection of 2D coordinates (x,y) to see if a given coordinate is in the collection, it needs to be as fast as possible and it will only be accessed from one thread.
( It's for collision checking )
Can someone give me a push in the right direction?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我能想到的绝对最快的方法是维护这些点的二维矩阵:
如果您不关心有多少个点,那么只需一个布尔矩阵就可以了。显然,只有在矩阵仅创建一次并且可能在将点添加到集合中时进行更新时,这才会很快。
简而言之,基本的 Collections 对此并不完美(尽管
HashSet
会很接近)。编辑
如果您还没有找到可以为您执行此操作的库,则可以轻松将其改编为
Set
。像这样的事情:The absolute fastest I can think of would be to maintain a 2D matrix of those points:
If you don't care how many there are, just a
boolean
matrix would work. Clearly this would only be fast if the matrix was created just once, and maybe updated as Points are added to the collection.In short, the basic Collections aren't perfect for this (though a
HashSet
would come close).Edit
This could be easily adapted to be a
Set<Point>
if you don't find a library that does this for you already. Something like this:我会使用一些 Trove 集合 数据结构。
如果您的点存储为几个
int
或几个float
,您可以将它们打包在long
中:x 坐标为 32 位y 坐标为 32 位。然后,您可以使用TLongHashSet
,它是针对原始数据进行优化的HashSet
(与普通 Java 集合相比,它速度更快,消耗的内存更少)。如果你有 int 坐标,那么就像
计算密钥然后使用它,
如果你有 float 值,你可以做同样的事情,但你必须打包 float
long
内的位。I would go using some Trove collections data structures.
If your points are stored as a couple of
int
or a couple offloat
you can pack them in along
: 32 bits for x-coord and 32 bits for y-coord. Then you can use aTLongHashSet
that is anHashSet
optimized for working with primitive data (it will be faster and consume less memory compared to normal java collections).If you have
int
coordinates it would be something liketo compute the key and then use it
if you have
float
values you can do the same thing, but you have to pack float bits inside thelong
.哈希集。其平均值为 O(1)。如果您想要真正的 O(1),您可以为您的对象创建一个包装器,该对象具有对集合的引用。这样你就不能仅仅将它与你拥有的收藏进行比较。
HashSet. Its O(1) average. If you want true O(1) you can make a wrapper for your object which has a reference to a collection. That way you cant just compare it with the collection you have.
与搜索集合相比,您需要多久更新一次集合?您应该基于此选择合适的数据结构。
Point2D 实现类似,对吗?那么你最好的选择可能是 TreeSet,它们的速度非常快,而且我相信它们依赖于 B+ 树,你可能知道 B+ 树在实际的数据库和文件系统中使用。
如果您认为要对结构进行大量更新,请查看 SkipList。它保证 O(log(operations)) **注意,这适用于您执行的所有操作,不保证单个操作的运行时间)
How often do you have to update the collection in comparison to searching it? You should chose an appropriate data structure based on that.
Point2D implements comparable, right? Then your best bet is probably a TreeSet, they are incredibly fast and I believe they rely on B+ trees, which you may know are used in actual databases and filesystems.
If you think you're going to be doing a fair amount of updates to the structure, take a look at the SkipList. It guarentees O(log(operations)) **NOTE this is for ALL operations you do, there is no guarentee about the runtime of a single opperation)
您可以尝试某种排序集,例如树集,因为您可以对其进行二分搜索。
You can try some sort of sorted set, like treeset, since you can do binary searches on it.