【问题标题】:Searching over a large List of objects quickly快速搜索大量对象列表
【发布时间】:2017-08-01 02:24:51
【问题描述】:

首先,我构建了一个包含大约 12,000 个对象的列表(通过读取现有文件),如下所示:

public class Operator
{
    string identifier; //i.e "7/1/2017 MN01 Day"
    string name1;
    string name2;
    string id1;
    string id2;
}

标识符在列表中是唯一的。

接下来我运行一个大型查询(目前大约有 400 万行,但它可能高达 1000 万行和大约 20 列)。然后我使用写入流将所有这些逐行写入 CSV。对于每一行,我都会遍历 Operator 列表以查找匹配项并添加这些列。

我遇到的问题是性能。我预计此报告需要很长时间才能运行,但我确定文件写入步骤花费的时间特别长(大约 4 小时)。我怀疑这与循环 Operator 列表 400 万次有关。

有什么办法可以提高这个速度吗?也许通过在我最初构建列表时做一些事情(可能是索引或排序),这将使搜索完成得更快。

【问题讨论】:

  • “我将所有这些都写入 CSV”向我们展示您的代码
  • 如果文件写入步骤花费了这么长时间,那可能是值得展示的代码......
  • 创建以标识符为键的运算符实例字典也可以加快查找匹配的速度。
  • 创建字典。要在 N 上找到匹配项,遍历每个项目将平均进行 N/2 次搜索。使用带有二进制散列的字典,搜索时间减少到 log2(N)。因此,您的搜索时间从 4,000,000/2 (2,000,000) 减少到 22。
  • 您绝对可以根据您需要从数据库结果中比较的任何内容将 12,000 个对象放入 DictionaryLookup 来加速循环,但我保证 IO(都检索从数据库中写入文件)将使循环超过 12,000 个项目所需的时间相形见绌。

标签: c#


【解决方案1】:

您应该能够通过构建 Dictionary(HashTable) 大大加快您的代码速度:

var items = list.ToDictionary(i => i.identifier, i => i);

然后您就可以在这本词典中编入索引:

var item = items["7/1/2017 MN01 Day"];

构建字典是一个O(n) 操作,查找字典是一个O(1) 操作。这意味着您的时间复杂度变为线性而不是指数。

【讨论】:

    【解决方案2】:

    ...而且,“您不能以某种方式将这些运算符放入数据库表中,以便您可以在 SQL 中使用某种JOIN 操作吗?”

    想到的另一种可能性是...... “20 个不同的查询,每个符号一个。” 或者,一个有 20 个分支的 UNION 查询。如果 SQL 引擎有任何方式使用索引来加速该过程,那么您仍然会领先。

    现在,可能会浪费大量时间,将数百万行中的每一行打包,通过网络线将它们喷射到您的机器上,结果却不得不丢弃其中的大部分,比如说,因为它们不匹配任何符号。

    如果您控制了数据库并且负担得起空间,并且如果大多数行不匹配任何符号,请考虑使用 symbols 表和 symbols_matched 表,第二个是多对-many 连接表,预先确定哪些行与哪些符号匹配。为了节省时间,这可能是值得的空间。 (填充此表的过程可以通过适当的插入、更新和删除事件放入存储过程 TRIGGERed...)

    【讨论】:

      【解决方案3】:

      没有看到任何代码,很难告诉你如何加快文件写入速度。

      但总的来说,可能值得考虑使用多线程编写。 This SO post 有一些有用的信息,您当然可以谷歌了解更多信息。

      【讨论】:

      • Careful, Sach ... 线程可能是一个真正令人头疼的问题,因为 一个 数据库服务器现在的任务是同时侦听多个线程 ... 还有什么这些线程正在做的事情,自然会与其他副本正在做的事情发生冲突。这实际上会使性能变得相当糟糕——当然,这完全取决于具体情况。线程可以是祝福,也可以是诅咒。 :-) ### 如果用户确实使用了哈希表,那将是一个巨大的改进(也许),即使没有线程,因为“它是比线性搜索更好的算法”。 ### JM2CW。
      • @MikeRobinson 是的,我同意你所说的,这就是为什么我没有说这是解决方案,但值得考虑。尤其是不知道 OP 究竟是如何编写的,所以不可能告诉他们什么是最好的解决方案,所以这是一个值得考虑的建议?顺便说一句,这就是 -1 的原因吗?
      猜你喜欢
      • 2011-11-22
      • 2010-11-28
      • 2016-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      • 2020-09-23
      相关资源
      最近更新 更多