分形渲染器中的HashSet性能问题

时间:2017-08-08 04:21:09

标签: java performance

使用案例

我试图改进我的应用程序来渲染Mandelbrot Set。我使用HashSets来检测集合中某点的轨道周期。

例如,-1的轨道是0,-1,0,-1 ......如果我把每个数字放到HashSet中,我可以通过比较HashSet的大小来检测无限循环。迭代次数。这样做会使渲染数量级更快。

当前实施:

正如我的程序所代表的那样,执行迭代的方法接收使用默认构造函数构造的HashSet(Integer类型)。这就是Java Mission Control向我展示的内容(典型输出,无论渲染的复杂性或深度如何):Screenshot showing that hashmap.put() and resize() take up 80% of processor time 迭代方法的运行时很小,几乎总是小于0.1毫秒。 (高变焦时,有时10ms)。结果,创建了大量这些哈希集,填充了~10-100k条目,然后立即转储。这会产生很多开销,因为HashSet必须经常调整大小。

我尝试过的无法工作的事情

  • 制作一个HashSet并清除它:通过支持地图的O(n)迭代绝对会杀死性能。
  • 使用initalCapacity参数使HashSet足够大以包含迭代:我尝试从1024到524288的每个2的幂,都使程序变慢。我的猜想关于为什么如下:由于我们有这么多的HashSets,java更快地用完了新的大块的大块,所以我们触发非常频繁的GC或类似的问题。

理想情况下,我希望两全其美:让一个物体足够大,然后清除它。但是,我似乎无法找到这样的数据结构。什么是存储这些数据的最佳方法?

1 个答案:

答案 0 :(得分:1)

根据我的经验,周期序列相当短,所以你应该使用数组并向后进行顺序搜索。您可以进行一些实验,例如,如果您只对60次迭代前的元素进行比较,则您已经捕获了长度为2,3,4,5,6,12,15和30的周期序列。计算一个元素mandelbrot轨道通常比在哈希集中找到(并插入)一个元素要快得多。

在这种情况下,进一步调整此方法也更容易,例如忽略前n个元素或使用一些epsilon来避免舍入错误。使用您的方法,您可以在我的理解中检查双值以获得严格相等。

祝你好运!