【问题标题】:Concurrent SortedList or O(log n) concurrent collection并发 SortedList 或 O(log n) 并发集合
【发布时间】:2014-04-28 02:53:48
【问题描述】:

我需要在 ASP.NET MVC 应用程序中缓存大量数据库中的数据,并希望使用 SortedList。我知道 .NET 4.0 添加了并发集合,但没有排序集合。 我正在考虑使用 SynchronizedCollection,但它甚至在读取时也大量使用锁(如果我没记错的话),所以我正在寻找其他选项。基本上我需要一个具有 O(log n) 访问复杂度的并发集合。

编辑 - 基于 Greg 答案的代码

void WrappedAdd(TKey k, TValue v)
{
  var copy = new SortedList<TKey, TValue>(_sortedList);
  copy.Add(k, v);
  _sortedList = copy;
}

【问题讨论】:

  • @HenkHolterman 我需要对集​​合进行排序。由于它会很大,我想避免 OrderByDesc 调用......
  • 您会退回整个收藏吗?单个项目不需要排序。一个 LINQ 哪里会是 O(n)。
  • @Blam 实际上我会将它用作集合(例如获取最近的记录)以及单项获取。这就是为什么我需要对它进行排序。对其进行排序将允许我使用二进制搜索,同时它将是一个集合/列表......
  • 顺便问一下,你希望有多少读者和作者?
  • 不,这不一样。不可变集合的关键在于它们使用结构共享。这意味着对它们的操作不会返回全新的集合,而是新版本与旧版本共享大部分结构,因此只需要很少的重新分配。 SortedList 不能这样工作。你在那里做的是一个接一个地复制集合中的每个元素。这是一个非常昂贵的O(n) 操作。

标签: c# .net asp.net-mvc caching


【解决方案1】:

你的要求很模糊,所以我真的不知道你想要什么。集合应该有索引吗?键值语义?

我不确定这是否符合您的要求,但您可以使用新的 Microsoft immutable collections library。它目前在 NuGet 上作为预览版提供。它包含排序集合(排序集和字典)等。

这些集合本身不是并发的(事实上,并发不是问题;它们不能被修改)。但是,您可以通过包装它们并在写入期间使用锁定来在并发设置中使用它们。读取是线程安全的,因为唯一的变异是分配一个引用,这是一个原子操作,因此您可以保证获得尽可能最新的结果。

它们是基于树的,所以大多数操作都是log n

public class ConcurrentWrapper<TKey, T> {
    ImmutableSortedDictionary<TKey, T> _inner;

    public void Add(TKey key, T item) {
        lock (_inner) {
            _inner = _inner.Add(key, item);
        }
    }

    public T Get(TKey key) {
        return _inner[key];
    }
}

【讨论】:

  • 谢谢格雷格。这与我正在寻找的非常接近。我看到的只有一个潜在问题......这不会给大型收藏品带来问题。由于每次添加都会为包含数百万条记录的大型集合返回一个新集合,这可能会占用所有内存。
  • 集合使用结构共享,这基本上意味着您将恢复旧集合,只需进行一些小的更改(通常不超过log n,可能更少)。这不应该导致内存问题,除非你已经快要达到你的内存上限了。不过,您可以期待更多的垃圾回收。
  • 实际上,即使使用 SortedList,这也可以工作......无论如何,读取都是线程安全的......我唯一需要做的就是类似于我上面更新的问题中的代码。跨度>
  • 似乎这就是我要走的路......还有一件事是有任何资源我可以看到这些新类在内部使用什么数据结构......我在想,因为我需要列表功能也可能与 ImmutableSortedSet 一起使用会更好。这种访问不会像 ImmutableSortedDictionary 那样有效,但值列表填充会更快...我只需要确认
  • 集合和字典基于不可变的 AVL 树(包括基于哈希的树;它们只是根据哈希排序)。我认为它们都基于相同的实现,所以不应该有太多的性能差异。我真的不知道为什么字典不支持按排序顺序索引键以及基于键的查找。数据结构支持O(log n) 中的能力。也许这是一种设计选择。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
  • 2014-06-13
  • 1970-01-01
  • 2011-12-11
相关资源
最近更新 更多