在log(n)时间内插入和更新,性能更好



我正在使用Java开发一些金融算法。我有一个复杂的数据结构,其中包含许多需要在算法生命周期内更新的属性。有时这个数据结构会更新1000多次......

为了提高性能,特别是对于get(search)/update/insert,我决定使用 TreeMap 作为容器,这在这方面非常有效。

现在是具有挑战性的部分。我需要更新数据结构属性,我需要从容器中检索它,这需要:

  1. 检查容器是否具有对象
  2. 如果是,则获取对象,否则创建新对象并添加到地图
  3. 更新对象(如果容器中存在)

这个过程需要三个 x log(n),即检查、获取和放置。我想在单个日志(n)时间内执行此操作。

为此,我的解决方案是:

我总是使用put在地图(insert/update/get)中添加对象。 put返回旧对象,我用旧值更新当前对象,这解决了 log(n),但不同的对象失去了对前一个对象的引用,因为新值在映射中被替换。

是否有更好的解决方案或更好的容器来更新数据结构。我可以使用List并使用集合的二叉搜索,但为此我需要再次对数据结构进行排序,因为列表未排序。

请指导

我认为你做得很好。

O(k.log(n)) = O(log(n))

其中 k 是一个常数。所以你的时间复杂度实际上是O(log(n))

如果你切换到ConcurrentMap.computeIfAbsent(...),你可以一口气实现12。它返回新/旧对象,以便您可以更新它。

如果是Java-7,那么放IfAbsent,但这需要额外的new - 如果建筑昂贵,这可能是一件坏事。

如果您不害怕周围有可变对象(您似乎已经给出了您提出的解决方案),您可以通过 1-2 个操作来完成。而不是

1. contains()
2a. exists? get(), modify, put()
2b. doesn't exist? create, put()

你可以做

1. get()
2a. null? create put()
2b. not-null? modify object contents, as you already have reference

这样,现有对象就有 1 个搜索操作,非现有对象有 2 个搜索操作。

如果你想进一步改进它,你可能想使用ConcurrentHashMap(在你克服了对哈希码的不信任之后;)和放置如果缺席

1. old = putIfAbsent(createFresh())
2. old not null? update old

说了这么多,我通常会尝试避免使用可变对象,因为可变对象的时间长于单个方法的生命周期。在某些时候,您可能希望多线程处理,并且具有可变的东西会使它变得更加复杂。但是有各种权衡(如内存压力),所以这取决于你。但是请认真研究哈希图,它们可能是您可以在这里进行的最大优化,无论对象(不)可变性如何。

最新更新