C# 编译的正则表达式性能不符合预期?
简言之,我在看Joe Albahari的C#5.0,在第26章中,他说,关于正则表达式: 在前面的一些示例中,我们使用相同的模式重复调用静态C# 编译的正则表达式性能不符合预期?,c#,.net,regex,C#,.net,Regex,简言之,我在看Joe Albahari的C#5.0,在第26章中,他说,关于正则表达式: 在前面的一些示例中,我们使用相同的模式重复调用静态RegEx方法。在这些情况下,另一种方法是使用模式实例化Regex对象,然后调用实例方法 这不仅仅是语法上的便利:在封面下。这将导致(高达10倍)更快的匹配,而代价是较小的初始编译成本(几十微秒) 所以好奇的我写了一个基准。该程序拆分一个字符串,迭代~3200万次调用Regex的静态调用和实例调用,以及执行相同任务的替代方法 class Program {
RegEx
方法。在这些情况下,另一种方法是使用模式实例化Regex
对象,然后调用实例方法
这不仅仅是语法上的便利:在封面下。这将导致(高达10倍)更快的匹配,而代价是较小的初始编译成本(几十微秒)
所以好奇的我写了一个基准。该程序拆分一个字符串,迭代~3200万次调用Regex
的静态调用和实例调用,以及执行相同任务的替代方法
class Program {
static void Main(string[] args) {
var str = "01/02/03/04/05/06/07/08/09/10";
var regex = new Regex("/");
var results = new List<Tuple<string, long>>();
for (int j = 0; j < 128; j++) {
var s = Stopwatch.StartNew();
for (var i = 0; i < 1024 * 1024; i++) {
RegexSplit(str);
}
s.Stop();
results.Add(new Tuple<string, long>("Regex", s.ElapsedTicks));
s = Stopwatch.StartNew();
for (var i = 0; i < 1024 * 1024; i++) {
CompiledRegexSplit(str, regex);
}
s.Stop();
results.Add(new Tuple<string, long>("Compiled", s.ElapsedTicks));
s = Stopwatch.StartNew();
for (var i = 0; i < 1024 * 1024; i++) {
StringSplit(str);
}
s.Stop();
results.Add(new Tuple<string, long>("String", s.ElapsedTicks));
Console.Write(".");
}
var resultsGroup = from it in results
group it by it.Item1
into g
select new {
Type = g.Key,
Avg = g.Average(git => git.Item2)
};
resultsGroup.ToList().ForEach(it => Console.WriteLine("{0}: {1:000000000.00}", it.Type, it.Avg));
}
static void StringSplit(string str) {
var split = str.Split('/');
}
static void CompiledRegexSplit(string str, Regex regex) {
var split = regex.Split(str);
}
static void RegexSplit(string str) {
var split = Regex.Split(str, "/");
}
}
根据这本书,这并不是我所期望的,我怀疑实例化一个Regex
需要1200万个刻度
此运行是在.NET4.5x64发布模式下进行的
对意外结果的解释是什么 您的代码只生成了一个Regex对象的实例。要使用实际编译的Regex对象,必须指定RegexOptions.compiled选项。这将通知Regex对象,它将以这样一种方式使用,即编译自身的前期成本是值得的,以便它可以更快地执行 之所以不自动执行此操作,是因为在有限的运行次数下,编译正则表达式的过程实际上要比节省的时间更长。Regex对象的存在是为了保存包含元数据(如Regex引擎选项等)的正则表达式,因此它可以在编译时使用,也可以不编译时使用 进行编译的代码是:
var regex = new Regex("/", RegexOptions.Compiled);
他所说的compile,可能是指RegexOptions.Compiled。Regex Regex=newregex(模式,RegexOptions.Compiled);你的正则表达式没有编译<代码>var regex=新regex(“/”)根据正则表达式编译的code>确实在构造函数中包含了Compiled标志。@Bidou他的代码示例列出了
RegEx r=newregex(@“sausage?”)
-updatedquestion@Bidou没有关系
Regex: 12257601.40
Compiled: 10869996.92
String: 01328636.27
var regex = new Regex("/", RegexOptions.Compiled);