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

标签 java performance

用例:

我正在尝试改进我的应用程序来渲染 Mandelbrot 集。我正在使用 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 毫秒。 (在高变焦时,有时为 10 毫秒)。结果,创建了很多这样的哈希集,填充了约 10-100k 条目,然后立即转储。这会产生大量开销,因为必须经常调整 HashSet 的大小。

我尝试过但不起作用的事情:

  • 创建一个 HashSet 并清除它:通过后备映射进行 O(n) 迭代绝对会降低性能。
  • 使用 initalCapacity 参数使 HashSet 足够大以包含迭代:我尝试了从 1024 到 524288 的每个 2 的幂,所有这些都会使程序变慢。我的猜测是这样的:由于我们有这么多的 HashSet,java 更快地用完新集合的大块,因此我们触发了非常频繁的 GC,或一些类似的问题。

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

最佳答案

根据我的经验,周期序列相当短,因此您应该使用数组并向后进行顺序搜索。您可以做一些实验,例如,如果您只与 60 次迭代前的元素进行比较,那么您已经捕获了长度为 2、3、4、5、6、12、15 和 30 的周期序列。计算曼德尔布罗轨道通常比在哈希集中查找(以及插入)元素快得多。

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

祝你好运!

关于java - 分形渲染器中的 HashSet 性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45559230/

相关文章:

javascript - 如何在AngularJS中等待多个请求完成

c# - 为什么将 List<T>.AddRange 方法设为通用方法会影响性能?

performance - Vaadin 在 Internet Explorer 中运行缓慢

java - hadoop mapreduce : java. lang.UnsatisfiedLinkError : org. apache.hadoop.util.NativeCodeLoader.buildSupportsSnappy()Z

java - 为什么Java中的抽象类有构造函数?

java - 如何在事件处理程序和回调中处理版本化对象

windows - 在本地主机上慢 Drupal | windows7 EasyPHP 64x

java - 是否有任何可与 dynaTrace 相媲美的开源框架?

java - 尽管之前在 AsyncTask 类中定义过,但 JSON 对象为 null?

java - 在MapReduce作业的Reducer中通过Text输入值进行多次迭代