【发布时间】:2013-09-16 14:22:21
【问题描述】:
您好,我正在尝试创建一个非常快速的算法来检测集合中的关键字或关键字列表。
在任何事情之前,我已经阅读了很多 stackoverflow(和其他)帖子,但无法将性能提高到我期望的水平。
我当前的解决方案能够在 0.1825 毫秒内分析 200 个字符的 输入 和 400 个列表的集合(在 1 毫秒内分析 5 个输入),但这太长了,我希望将此性能至少提高 5 倍(这是我的要求)。
解决方案测试:
- 手动研究
- 高度复杂的正则表达式(组、反向引用...)
- 多次调用简单的正则表达式(以匹配每个关键字)
- 简单的正则表达式匹配输入关键字,然后与跟踪的关键字相交(当前解决方案)
- 多线程(对性能的巨大影响 (*100),所以我不确定这是否是解决此问题的最佳解决方案)
目前的解决方案:
input (string) : 解析并分析其中包含的关键字列表的字符串。 示例:“你好,世界!#piloupe 先生你好吗?”。
tracks (string[]) : 我们要匹配的字符串数组(空格表示 AND)。示例:“hello world”匹配一个同时包含 'hello' 和 'world' 的字符串,无论它们的位置是什么
keywordList (string[][]) : 输入匹配的字符串列表。 示例:{ { "hello" }, { "#piloupe" }, { "hello", "world" } }
uniqueKeywords (string[]) : 表示keywordList的所有唯一关键字的字符串数组。使用前面的关键字列表:{ "hello", "#piloupe", "world" }
所有这些先前的信息不需要进行任何性能改进,因为它们只针对任何输入构建一次。
查找轨迹算法:
// Store in the class performing the queries
readonly Regex _regexToGetAllInputWords = new Regex(@"\#\w+|\w+", RegexOptions.Compiled);
List<string> GetInputMatches(input)
{
// Extract all the words from the input
var inputWordsMatchCollection = _regexToGetAllInputWords.Matches(input.ToLower()).OfType<Match>().Select(x => x.Value).ToArray();
// Get all the words from the input matching the tracked keywords
var matchingKeywords = uniqueKeywords.Intersect(inputWordsMatchCollection).ToArray();
List<string> result = new List<string>();
// For all the tracks check whether they match
for (int i = 0; i < tracksKeywords.Length; ++i)
{
bool trackIsMatching = true;
// For all the keywords of the track check whether they exist
for (int j = 0; j < tracksKeywords[i].Length && trackIsMatching; ++j)
{
trackIsMatching = matchingKeywords.Contains(tracksKeywords[i][j]);
}
if (trackIsMatching)
{
string keyword = tracks[i];
result.Add(keyword);
}
}
return result;
}
任何帮助将不胜感激。
【问题讨论】:
-
你如何测试性能?
-
看一眼您的代码,似乎使用 Parallel LINQ 可以加快多核系统的速度。
-
你有没有打破这个时间?我很想知道
List<string> result = new List<string>();之前还是之后需要更长时间。 -
你如何测试性能:我在调用方法之前启动秒表并在调用之后停止它。
标签: c# regex performance parsing