C# “高性能”;包括「;在C中的字符串列表中搜索#

C# “高性能”;包括「;在C中的字符串列表中搜索#,c#,string,search,sorting,contains,C#,String,Search,Sorting,Contains,我有一个大约500000个字符串的列表,每个字符串大约100个字符长。给定一个搜索词,我想标识列表中包含该搜索词的所有字符串。目前,我正在使用Select方法(“MATCH%term%”对一个普通的旧数据集执行此操作。我的笔记本电脑大约需要600毫秒。我想加快速度,可能是100-200米 推荐的方法是什么 性能至关重要,因此我可以在必要时(在合理范围内)用内存占用换取更好的性能。字符串列表在初始化后不会更改,因此计算哈希也是一个选项 有人有什么建议吗?哪些C#数据结构最适合这项任务 您是否尝试过

我有一个大约500000个字符串的列表,每个字符串大约100个字符长。给定一个搜索词,我想标识列表中包含该搜索词的所有字符串。目前,我正在使用Select方法(“MATCH%term%”对一个普通的旧数据集执行此操作。我的笔记本电脑大约需要600毫秒。我想加快速度,可能是100-200米

推荐的方法是什么

性能至关重要,因此我可以在必要时(在合理范围内)用内存占用换取更好的性能。字符串列表在初始化后不会更改,因此计算哈希也是一个选项


有人有什么建议吗?哪些C#数据结构最适合这项任务

您是否尝试过将字符串加载到
列表中,然后使用Linq扩展
Contains
方法

var myList = new List<string>();
//Code to load your list goes here...

var searchTerm = "find this";
var match = myList.Contains(searchTerm);
var myList=new List();
//加载列表的代码位于此处。。。
var searchTerm=“查找此”;
var match=myList.Contains(searchTerm);

我听说在执行快速全文搜索方面有很多好处。他们已经完成了找出最快的数据结构等工作。我建议你试试看

否则,您可以尝试以下方法:

var matches = list.AsParallel().Where(s => s.Contains(searchTerm)).ToList();
但它可能不会让你降低到100毫秒。

一个trie或将有助于加快这一速度-这基本上就是全文搜索(通常)所使用的

您可以使用C#中的一些实现,也可以看到这个SO线程:

正如@leppie所提到的,并行执行可能已经为您提供了您正在寻找的x3性能增益。但是,您必须再次仔细测量,否则这是任何人的猜测。

公共静态bool ContainsFast(此IList列表,T项)
public static bool ContainsFast<T>(this IList<T> list, T item)
{
    return list.IndexOf(item) >= 0;
}
{ 返回列表。IndexOf(项)>=0; }

根据我所做的测试,我这边的
Contains
的这个变体大约快了33%。

您应该尝试使用Dictionary类。 它比列表快得多,因为它是一个索引搜索

Dictionary<String, String> ldapDocument = new Dictionary<String, String>();
//load your list here
//Sample -> ldapDocument.Add("014548787","014548787");
var match = ldapDocument.ContainsKey(stringToMatch);
Dictionary ldapDocument=newdictionary();
//在这里加载您的列表
//Sample->ldapDocument.Add(“014548787”、“014548787”);
var match=ldapDocument.ContainsKey(stringToMatch);

您是否尝试过以下方法

list.FindAll(x => x.Contains("YourTerm")).ToList();
由于某些原因,我的电脑上的List.AsParallel().Where(…)比List.FindAll(…)慢

list.AsParallel().Where(x => x.Contains("YourTerm")).ToList();
希望这能对您有所帮助。

检查字符串中是否出现字符串的最快方法如下:

for (int x = 0; x < ss.Length; x++)
    for (int y = 0; y < sf.Length; y++
        c[y] += ((ss[x].Length - ss[x].Replace(sf[y], String.Empty).Length) / sf[y].Length > 0 ? 1 : 0);
for(int x=0;x0?1:0);
因此,你可以:

  • 使用Parallel.For构造在列表中循环
  • 实现上述代码以检查字符串是否包含要搜索的内容。“SS”是要搜索的字符串的字符串[];“SF”是要搜索的字符串的字符串[];c[y]是找到的每个字符串的总计数

  • 显然,您必须使它们适应您的列表[字符串](或您正在使用的任何数据结构).

    此任务似乎非常适合并行执行。您有多少CPU内核?加上Boyer Moore,应该会有足够的改进。您是否尝试过加载到数据库中,让数据库引擎做它擅长的事情?您是否在寻找单词或任意子字符串?MongusPong:我没有数据库,我认为这不会ld更快。DB无法利用索引,因为“LIKE%…%”子句。我正在寻找一个定制的优化。Gabe:任意子字符串。如果我在寻找单词,我可以标记字符串并建立自己的索引。@leppie为什么要使用BM?有多种字符串搜索算法(Aho Corasick,Wu Manber)或者尝试。我认为只有当列表中的一个字符串正是要搜索的字符串时,才会匹配。提出问题的人也希望查看所有这些字符串。是的,为了适合OP,您必须执行
    myList.Where(s=>s.Contains(searchTerm))
    。您可以在其中抛出一个
    AsParallel
    ,使查询并行运行,并且您可以将参数调整为
    string。如果您知道您想要的是精确匹配,而不是区域性匹配,则包含
    。即使如此,您也不会得到速度上的数量级差异。很好的建议条带化。并行处理可能会给我带来所需的提升。我需要尝试一下。谢谢@Paige Cook,使用字符串列表是一个很好的建议;它的速度快得多。现在搜索速度下降到50毫秒左右。我只能接受一个答案,所以我接受了条带化,因为它包括使用Linq根据问题的要求查询列表。它可能更快这仅仅是因为它做的是一个精确的比较,而不是一个文化敏感的比较。它也不检查子字符串,这是OP的一个要求。
    包含的内容是fast
    ?感谢您的建议。Lucene看起来是一个相当大的开销(在框架方面)只针对这一种情况,但我可以看看。你知道它是否处理任意子字符串吗?如果它将字符串标记为单词,那么它的自由文本搜索将不会有帮助。@njreed.myopenid.com:我根据我对另一个问题的评论更新了我的答案。不过,考虑到要求,你可能需要更改算法才能获得性能您正在寻找的e boost。谢谢@StriplingWarrior。搜索现在已下降到大约50ms。我不需要实现任何特殊算法。将Linq与字符串列表结合使用就足够了。我猜数据集带来的开销比我想象的要大。谢谢您的建议。我将看看并行执行带来了多少boost,而不是hen看看我是否需要对实现进行更改。字典很好,但它们只根据精确的键编制索引。他想要一个“包含”搜索。