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

时间:2016-01-28 11:40:11

标签: java algorithm dictionary binary-search-tree

我正在使用Java开发一些财务算法。我有一个复杂的数据结构,有许多属性需要在算法的生命周期内更新。有时这个数据结构更新超过1000次......

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

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

  1. 检查容器是否包含对象
  2. 如果是,则获取对象,否则创建新对象并添加到地图
  3. 更新容器中存在的对象
  4. 这个过程需要三个x log(n),即check,get和put。我想在SINGLE log(n)时间内执行此操作。

    为此,我的解决方案是:

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

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

    请指导

3 个答案:

答案 0 :(得分:1)

我觉得你做得很好。

  

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

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

答案 1 :(得分:1)

如果切换到ConcurrentMap.computeIfAbsent(...),您可以在一次点击中获得12。它返回新/旧对象,以便您可以更新它。

如果Java-7那么putIfAbsent但是需要额外的new - 如果构造很昂贵,也许是件坏事。

答案 2 :(得分:1)

如果你不害怕周围有可变物体(你似乎给出了你提出的解决方案),你可以用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(在你克服了对哈希码的不信任之后;)和putIfAbsent

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

说这一切,我通常试图避免可变对象的事情比单一方法的生命周期更长。在某些时候,您可能希望多线程处理您的处理,并且具有可变的东西将使其变得更加复杂。但是存在各种权衡(例如记忆压力),所以这取决于你。但请认真研究一下哈希图,它们可能是你在这里可以做到的最大优化,无论对象(im)是否可变。