【问题标题】:Better way to search a List for a string在列表中搜索字符串的更好方法
【发布时间】:2017-05-26 12:37:08
【问题描述】:

我已经使用以下代码在对象列表中搜索特定值:

List<customer> matchingContacts = cAllServer
  .Where(o => o.customerNum.Contains(searchTerm) || 
              o.personInv.lastname.Contains(searchTerm) || 
              o.personDel.lastname.Contains(searchTerm))
  .ToList();

是否有更快或更简洁的方法来实现此搜索?

【问题讨论】:

  • 为什么?这比您预期的要慢吗?
  • 这是我知道的唯一方法,它将搜索对象中指定的所有字符串字段并返回这些列表项,这更多的是关于是否有任何潜在的优化或更清洁的问题暗示的方式。
  • @DanHall 没有,没有
  • 是的。这本质上是全文搜索。如果cAllServer 是数据库服务器,则可以使用服务器的 FTS 功能。例如,SQL Server 提供 FTS。如果cAllServer 是一个内存列表,您必须创建一个单独的结构来加速 FTS 搜索。就像 BTree 一样,有一些容器可以加速此类搜索,尽管它们并非微不足道
  • @John 我想你的意思是for,而不是foreach,虽然这只是一个微优化。

标签: c# linq search


【解决方案1】:

由于您必须遍历所有列表项,因此复杂度为 O(n)。性能还取决于您是在 IQueryable 集合(有或没有延迟加载)上操作,还是它是一个序列化的 IEnumerable 集合。我建议首先检查最有可能具有您正在搜索的值的属性,因为您使用的是“或”运算符,以便您可以加快“包含”操作。如果您知道它在 10 毫秒而不是 25 毫秒内与特定实体匹配,那么您的迭代速度会更快。还有一个流行的说法是什么更快?包含还是 IndexOf?好吧 IndexOf 应该快一点,但我怀疑你会注意到它,除非你对包含数百万个元素的列表进行操作。 Is String.Contains() faster than String.IndexOf()?

【讨论】:

    【解决方案2】:

    我认为这很好,但另一方面我会三思而后行转换为列表的需要,你已经收到了一个 IEnumerable 类型,它可以让你遍历东西。除非您需要来回移动列表并按索引搜索,否则您无需将其转换为列表。

    不过,这是一个小的优化。

    【讨论】:

      【解决方案3】:

      我建议的一件事是创建一个新的“searchtext”列,预先填充(o.customerNum + "|" + o.personInv.lastname + "|" + o.personDel.lastname).ToUpper()

      List<customer> matchingContacts = cAllServer
        .Where(o => o.searchtext.Contains(searchTerm))
        .ToList();
      

      这执行一个搜索而不是三个(但在更长的字符串上),如果您使用.ToUpper() searchTerm,您可以执行区分大小写的搜索,这可能会更快。

      总的来说,我不认为这会明显更快。

      【讨论】:

        猜你喜欢
        • 2021-05-29
        • 2014-07-12
        • 2019-04-06
        • 1970-01-01
        • 2012-01-29
        • 1970-01-01
        • 2020-03-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多