【问题标题】:Filtering a sub set of (potentially) 1.000.000+ items过滤(可能)1.000.000+ 个项目的子集
【发布时间】:2011-05-23 08:51:45
【问题描述】:

我有一个很大的dataset,可能超过一百万个条目。所有项目都有一个分配的时间戳,并且项目在运行时被添加到集合中(通常,但不总是,具有较新的时间戳)。 我需要在给定的时间范围内显示这些数据的子集。与整个数据集相比,此时间范围通常非常小,即在 1.000.000 多个项目中,不超过约 1000 个在该给定时间范围内。这个时间范围以恒定的速度移动,例如每秒时间范围移动一秒。 此外,用户可以随时调整时间范围(“移动”数据集)或设置其他过滤器(例如,通过某些文本过滤)。

到目前为止,我并不担心性能,而是尝试将其他事情做好,并且只使用较小的测试集。我不太确定如何有效地解决这个问题,并且会为每一个输入感到高兴。谢谢。

编辑:使用的语言是 C# 4。

更新:我现在使用间隔树,可以在这里找到实现: https://github.com/mbuchetics/RangeTree

它还附带一个异步版本,该版本使用任务并行库 (TPL) 重建树。

【问题讨论】:

  • 数据集是否按时间戳排序?
  • 您使用什么数据结构来存储 1000000 + 个项目?
  • 这是一个DataSet 对象还是当你说数据集时你指的是一个数据库?
  • mtrw:是的。但是,会不断添加其他项目,因此需要重新排序。 Saurabh:现在是一个简单的 Dictionary 和一个 SortedList。 jvanrhyn:两者都不是,数据集是从文件中加载的。
  • 上帝创造 SQL 的第 8 天。有时它很丑陋,但很管用。

标签: c# .net algorithm search filtering


【解决方案1】:

我们在开发过程中遇到了类似的问题 - 必须收集数百万按某个键排序的项目,然后根据需要从中导出一页。我发现你的问题有点相似。

为此,我们通过以下方式调整了red-black tree 结构:

  • 我们向其中添加了迭代器,因此我们可以在 o(1) 中获得“下一个”项
  • 我们添加了从“索引”中查找迭代器,并设法在 O(log n) 中完成此操作

RB Tree 的插入复杂度为 O(log n),所以我猜你的插入很适合。

迭代器上的next()是通过添加和维护所有叶子节点的链表来实现的——我们最初采用的RB Tree实现没有包含这个。

RB Tree 也很酷,因为它允许您根据需要微调节点大小。通过试验,您将能够找出适合您问题的正确数字。

【讨论】:

  • +1 用于提及复杂性并提供科学背景。
  • @Aliostad:我很想与它分享我的经验 - 我们有一个限制,即我们应该能够在不到 100 毫秒的时间内从中获取任何页面
  • 实际上没有必要构建自己的数据结构 - 任何标准库都应该带有某种排序的映射原语。
  • @NickJohnson 确实需要自己动手,因为每一点特定领域的知识都能够帮助我们从内存使用和 CPU 负载方面挤出更多的东西。
  • daniel 你名字中看起来很滑稽的 S 怎么读?
【解决方案2】:

使用按时间戳排序的SortedList

您所要做的就是对排序列表中的排序键执行二进制搜索,以找到您选择的边界,这非常容易。

【讨论】:

    【解决方案3】:

    将新项目插入排序列表。这将使您可以很容易地选择一个范围。如果您熟悉 linq,您也可以使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      • 2010-10-17
      • 2011-11-07
      • 1970-01-01
      相关资源
      最近更新 更多