【问题标题】:What's the efficient way to search and filter ObservableCollection搜索和过滤 ObservableCollection 的有效方法是什么
【发布时间】:2010-03-04 09:09:11
【问题描述】:

我有一个包含大约 100 万条记录的数据库。我的应用程序对这些记录进行频繁的增量搜索并过滤 UI 列表。该场景更像是“电话联系人搜索”。
目前我正在关注这个:

  1. 将数据加载到数据源层中的List<myModel>`
  2. 将其发送到 MainViewModel
  3. List<myModel> 加载到ObservableCollection<myViewModel> (绑定到 ListView)
  4. 根据关键字,过滤`ObservableCollection
  5. 在关闭应用程序时,更新数据库 [自 ObservableCollection 也可能是 由用户更新]

我的问题:

  • 这是有效的方法吗?
  • 现在我的应用程序消耗大约 30 到 50 MB 的内存。公平吗?
  • 或者我应该在数据库中执行我的搜索吗? [但我不能在速度上妥协]
  • 是否应该始终创建 myModel 列表并将其加载到我的 ObservableCollection 中?
  • 还建议我使用非常适合增量搜索的过滤技术(第 4 点)。目前我有一个 GenericList 包含整个集合以供查找并将过滤的项目添加到 ObservableCollection,清除所有以前的项目。

编辑:之前我只检查了 37k 条记录的内存消耗。 250k条记录,内存消耗超过100MB:(。所以现在我计划只在内存中保留10k条记录,如果超过了我会查询db。有什么建议吗?

提前致谢, 转向

【问题讨论】:

    标签: wpf search mvvm filter observablecollection


    【解决方案1】:

    您可以在不中断用户工作流程或对性能造成巨大影响的情况下执行多种操作。

    现在我的应用程序消耗了大约 30 到 50 MB 的内存。这公平吗?

    对于 .net 应用程序来说这是正常的。您会注意到启动应用程序后的内存占用量并没有小很多。

    或者我应该在 数据库代替? [但是我不能 速度妥协]

    仅当您一开始无法一步加载数据时,重复查询数据库才是合适的。每当用户在框中键入时,您要确保您不是在每次更改搜索条件时都查询数据库,而是在其中有一个短计时器,等待一秒钟左右,然后再使用新的查询数据库标准。在重新查询数据库时,它还可能有助于减少通过分页显示的记录数或在用户开始滚动时延迟加载其余数据。适当的数据库索引将帮助您显着降低此类查询的执行速度。

    但是,如果您可以将整个列表保存在内存中(例如,一步从数据库中查询它不会太大,或者无论如何您都需要向用户显示整个列表),最好保留一个列表的原始副本,并拥有该列表的副本,您可以逐步过滤。因此,您需要检查您的搜索条件是否是先前搜索条件的子集。如果是这样,您可以过滤已经过滤的列表,否则您需要过滤原始列表。这可以使用 LINQ .Where() 运算符有效地实现,并在必要时使用 PLINQ 并行化。 .Where() 展示 O(n) 时间 AFAIK。

    这可以通过使用带有适当键的 HashSet 来改进。

    【讨论】:

    • 但是数据库索引没有帮助,因为我的搜索模式是 '%keyword%' 类型
    • 除了向前查询之前的搜索之外,我还尝试在按下退格键时使用列表。但恐怕这是一个不好的做法
    • 你能详细解释一下HashSet部分吗?
    • HashSet 是另一种将对象集合保存在内存中的方法。哈希集背后的想法是,它使用对象的哈希(通过Object.GetHasCode 检索)来构建一个字典,其中哈希作为键,对象作为值。因此,所有典型操作(插入、检索、删除)通常都可以在 O(log(n)) 中发生。最坏的情况是 O(n),但几乎不可能发生(所有对象都需要散列到相同的值)。您可以在 wikipedia 上阅读有关 Hashset 的信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 1970-01-01
    • 2021-07-07
    • 2010-10-26
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    相关资源
    最近更新 更多