解析文件中的文本的代码在c#中会减慢到一半
本文关键字:一半 代码 文件 文本 | 更新日期: 2023-09-27 18:09:05
private static void BuildDictionaryOfRequires(Regex exp, Dictionary<string, string> dictionary, DirectoryInfo dir)
{
var i = 0;
var total = dir.EnumerateFiles("*.*", SearchOption.AllDirectories).
Where(x => x.Extension == ".aspx" || x.Extension == ".ascx").Count();
foreach (var item in dir.EnumerateFiles("*.*", SearchOption.AllDirectories).
Where(x => x.Extension == ".aspx" || x.Extension == ".ascx"))
{
#if DEBUG
Stopwatch sw = Stopwatch.StartNew();
#endif
var text = File.ReadAllText(item.FullName);
MatchCollection matches = exp.Matches(text);
foreach (Match match in matches)
{
var matchValue = match.Groups[0].Value;
if (dictionary.ContainsKey(matchValue))
{
dictionary[matchValue] = string.Format("{0},{1}", dictionary[matchValue], item.Name);
}
else
{
dictionary.Add(matchValue, item.Name);
}
}
Console.WriteLine(string.Format("Found matches in {0}.", item.Name));
#if DEBUG
sw.Stop();
Console.WriteLine("Time used (float): {0} ms", sw.Elapsed.TotalMilliseconds);
#endif
Console.WriteLine(string.Format("{0} of {1}", (++i).ToString(), total));
}
}
, lambda找到大约232个文件。它通过了160英里,然后就开始爬行了。我现在正在分析代码,但想知道是否有什么明显的我做错了。
正则表达式是
Regex exp = new Regex(@"dojo'.require'([""']['w'.]+['""]');?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
所有的文件长度和结构相似。
大多数文件占用不到30ms,但有些文件占用11251 ms。
使用更新的正则表达式,整个过程现在需要1700ms。唷!
尝试简化你的正则表达式:
Regex exp = new Regex(@"dojo'.require'([""']['w'.]+[""']')", RegexOptions.IgnoreCase | RegexOptions.Compiled);
UPDATE:如果您想匹配您的示例,则删除末尾的分号
我认为当前有问题的部分是这里的正则表达式:
('w+'.?)*
去掉?然后加上'w*
,你将匹配所有相同的字符串,但效率更高。
('w+'.?)*
可以通过多种方式匹配asdf
:
- asdf
- asd, f
- , d, f
- a, s, d, f
- , sd, f
- a, s, df
- ,自卫队
- , df
我猜你的一些文件有一堆这样的行:
dojo.require('asdf') //with no ;
你的正则表达式将失败的最贪婪的匹配,然后尝试每一个其他的组合,直到它最终没有得到任何匹配。随着'asdf'
字符串的增长,这会变得非常昂贵。
尝试使用:
Regex exp = new Regex(@"dojo'.require'(('""|'')(('w+'.)*'w*)('""|'')');");
几点:
- 取出DiscardBufferedData调用。你不需要它,而且它是昂贵的。
- 修复双重处置。请注意Close也调用Dispose,所以你也可以摆脱那个。
- 事实上,有文件。ReadAllText方法,可以用来摆脱你正在构建和处理的流阅读器。