编辑:我收到了一些非常好的建议,我将尝试通过它们并在某些时候接受答案
我有一个很大的字符串列表(800k),我希望尽快过滤掉不需要的单词列表(最终亵渎但可能是任何东西).
我最终希望看到的结果将是一个列表,如
Hello,World,My,Name,Is,Yakyb,Shell
会成为
World,My,Name,Is,Yakyb
经过检查后
Hell,Heaven.
到目前为止我的代码是
var words = items
.Distinct()
.AsParallel()
.Where(x => !WordContains(x, WordsUnwanted));
public static bool WordContains(string word, List<string> words)
{
for (int i = 0; i < words.Count(); i++)
{
if (word.Contains(words[i]))
{
return true;
}
}
return false;
}
目前这需要大约2.3秒(9.5 w / o并行)来处理800k字,这对于一次性来说并不是什么大不了的事.但是,学习过程是否有更快的处理方式?
不需要的单词列表长100个单词
没有一个词包含标点符号或空格
>采取措施删除所有列表中的重复项
>步骤查看是否更快地使用数组(不是)有趣地将参数单词更改为字符串[]使其慢25%
>步骤添加AsParallel()将时间缩短到~2.3秒
最佳答案 尝试使用名为Except的方法.
http://msdn.microsoft.com/en-AU/library/system.linq.enumerable.except.aspx
var words = new List<string>() {"Hello","Hey","Cat"};
var filter = new List<string>() {"Cat"};
var filtered = words.Except(filter);
还怎么样:
var words = new List<string>() {"Hello","Hey","cat"};
var filter = new List<string>() {"Cat"};
// Perhaps a Except() here to match exact strings without substrings first?
var filtered = words.Where(i=> !ContainsAny(i,filter)).AsParallel();
// You could experiment with AsParallel() and see
// if running the query parallel yields faster results on larger string[]
// AsParallel probably not worth the cost unless list is large
public bool ContainsAny(string str, IEnumerable<string> values)
{
if (!string.IsNullOrEmpty(str) || values.Any())
{
foreach (string value in values)
{
// Ignore case comparison from @TimSchmelter
if (str.IndexOf(value, StringComparison.OrdinalIgnoreCase) != -1) return true;
//if(str.ToLowerInvariant().Contains(value.ToLowerInvariant()))
// return true;
}
}
return false;
}