Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 编译的正则表达式性能不符合预期?_C#_.net_Regex - Fatal编程技术网

C# 编译的正则表达式性能不符合预期?

C# 编译的正则表达式性能不符合预期?,c#,.net,regex,C#,.net,Regex,简言之,我在看Joe Albahari的C#5.0,在第26章中,他说,关于正则表达式: 在前面的一些示例中,我们使用相同的模式重复调用静态RegEx方法。在这些情况下,另一种方法是使用模式实例化Regex对象,然后调用实例方法 这不仅仅是语法上的便利:在封面下。这将导致(高达10倍)更快的匹配,而代价是较小的初始编译成本(几十微秒) 所以好奇的我写了一个基准。该程序拆分一个字符串,迭代~3200万次调用Regex的静态调用和实例调用,以及执行相同任务的替代方法 class Program {

简言之,我在看Joe Albahari的C#5.0,在第26章中,他说,关于正则表达式:

在前面的一些示例中,我们使用相同的模式重复调用静态
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(“/”)确实在构造函数中包含了Compiled标志。@Bidou他的代码示例列出了
RegEx r=newregex(@“sausage?”)
-updatedquestion@Bidou没有关系
Regex:    12257601.40
Compiled: 10869996.92
String:   01328636.27
var regex = new Regex("/", RegexOptions.Compiled);