订单很少变化的快速排序

时间:2011-10-04 22:20:31

标签: java performance sorting

我正在制作一个带有滚动视图的2D游戏(想想Red Alert或Zelda),但我正在绘制图纸。

基本上,地图上绘制了两种类型的对象。有些人有固定的位置(如树木和建筑物),而其他人则四处移动(玩家,敌人,飞箭)。

如果事物以正确的方式出现在彼此前面,则需要按特定顺序绘制(首先是远处的物体,然后朝“相机”方向工作)。

现在我每次游戏更新(每秒100次)时都会对所有对象(两种)的列表进行排序,这感觉就像是浪费了大量的CPU时间。对象的顺序很少变化,当它们发生时,它们通常只在列表中向上或向下移动一个位置。

另一个问题是,只需要考虑实际在屏幕上的对象。由于地图可能变得非常大,有1000个物体,我不想每秒100次对它们进行排序。

你怎么建议我解决这个问题?

5 个答案:

答案 0 :(得分:5)

Bubble Sort最好的情况是元素已经排序。在这种情况下,你会得到O(n)比较。根据维基百科:

  

在计算机图形学中,它能够在几乎排序的数组中检测一个非常小的错误(比如只交换两个元素),并且只需线性复杂度(2n)即可修复它。

但由于链接文章中提到的各种原因,它被认为是一种“糟糕”的算法。您可能想要分析它与插入排序(对于排序列表也是O(n))之间的差异,以查看哪些在实践中更快。

另一种选择是使用一种数据结构来保存已排序的项目,并在项目的位置发生变化时得到通知。如果与重新绘制的对象相比,对象不会移动很多,那么这将节省大量的处理时间,因为您只需要重新排序其位置已更改的元素,您可以避免重新排序直到至少有一个元素移动为止。

答案 1 :(得分:1)

跟踪矢量中屏幕上的哪些对象,并在其末尾添加新显示的对象。使用冒泡排序或插入排序进行排序。对于随机数据,这种效率可能会增加,但对于几乎已排序的数据,这几乎是无效的。

答案 2 :(得分:1)

同意泡沫和插入种类。

我有其他想法没有排序:如果很少更改订单,您只能跟踪更改历史记录并在需要排序时恢复订单。此外,如果没有添加或删除元素,只需恢复原始有序列表的快照,它将非常容易和快速。如果我清楚地理解你的问题。

答案 3 :(得分:0)

考虑使用PriorityQueue,或者可能是双向链表,这样您就可以在需要时直接重新定位项目,而不是基于Z顺序强制执行。您还应该彻底调查剪辑区域。

答案 4 :(得分:0)

排序100个对象不会花费很长时间。但是,如果性能确实很重要,并且您知道列表几乎可以排序,几乎没有项目,那么合并排序或Tim排序算法可能会给您带来良好的性能。它对已经排序的列表具有O(N)性能,或者只有少数元素无序。

那就是说,忽略了Java库提供的通用排序算法,直到你测量了它的实际性能。由于它是通用的,它应该以一种为各种情况提供合理性能的方式实施,包括列表几乎已经分类的情况。

事实上,标准的Java排序方法使用了合并排序到Java 6,并使用Java 7更改为TimSort。