【发布时间】:2012-04-09 20:16:05
【问题描述】:
我正在使用以下代码针对已编译的正则表达式测试 CompileToAssembly 性能,但结果不合适。请让我知道我错过了什么。谢谢!!!
static readonly Regex regex = new Regex(@"(stats|pause\s?(all|\d+(\,\d+)*)|start\s?(all|\d+(\,\d+)*)|add\s?time\s?(all|\d+(\,\d+)*)(\s\d+)|c(?:hange)?\s?p(?:asskey)?|close)(.*)", RegexOptions.Compiled);
static readonly Regex reg = new Regex(@"(stats|pause\s?(all|\d+(\,\d+)*)|start\s?(all|\d+(\,\d+)*)|add\s?time\s?(all|\d+(\,\d+)*)(\s\d+)|c(?:hange)?\s?p(?:asskey)?|close)(.*)");
static readonly Regex level4 = new DuplicatedString();
static void Main()
{
const string str = "add time 243,3453,43543,543,534534,54534543,345345,4354354235,345435,34543534 6873brekgnfkjerkgiengklewrij";
const int itr = 1000000;
CompileToAssembly();
Match match;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < itr; i++)
{
match = regex.Match(str);
}
sw.Stop();
Console.WriteLine("RegexOptions.Compiled: {0}ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int i = 0; i < itr; i++)
{
match = level4.Match(str);
}
sw.Stop();
Console.WriteLine("CompiledToAssembly: {0}ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int i = 0; i < itr; i++)
{
match = reg.Match(str);
}
sw.Stop();
Console.WriteLine("Interpreted: {0}ms", sw.ElapsedMilliseconds);
Console.ReadLine();
}
public static void CompileToAssembly()
{
RegexCompilationInfo expr;
List<RegexCompilationInfo> compilationList = new List<RegexCompilationInfo>();
// Define regular expression to detect duplicate words
expr = new RegexCompilationInfo(@"(stats|pause\s?(all|\d+(\,\d+)*)|start\s?(all|\d+(\,\d+)*)|add\s?time\s?(all|\d+(\,\d+)*)(\s\d+)|c(?:hange)?\s?p(?:asskey)?|close)(.*)",
RegexOptions.Compiled,
"DuplicatedString",
"Utilities.RegularExpressions",
true);
// Add info object to list of objects
compilationList.Add(expr);
// Apply AssemblyTitle attribute to the new assembly
//
// Define the parameter(s) of the AssemblyTitle attribute's constructor
Type[] parameters = { typeof(string) };
// Define the assembly's title
object[] paramValues = { "General-purpose library of compiled regular expressions" };
// Get the ConstructorInfo object representing the attribute's constructor
ConstructorInfo ctor = typeof(System.Reflection.AssemblyTitleAttribute).GetConstructor(parameters);
// Create the CustomAttributeBuilder object array
CustomAttributeBuilder[] attBuilder = { new CustomAttributeBuilder(ctor, paramValues) };
// Generate assembly with compiled regular expressions
RegexCompilationInfo[] compilationArray = new RegexCompilationInfo[compilationList.Count];
AssemblyName assemName = new AssemblyName("RegexLib, Version=1.0.0.1001, Culture=neutral, PublicKeyToken=null");
compilationList.CopyTo(compilationArray);
Regex.CompileToAssembly(compilationArray, assemName, attBuilder);
}
结果如下:
RegexOptions.Compiled: 3908ms
CompiledToAssembly: 59349ms
Interpreted: 5653ms
【问题讨论】:
-
我自己运行了代码。这是我的结果:
RegexOptions.Compiled: 8399ms;CompiledToAssembly: 7806ms;Interpreted: 10405ms。正是我所期望的。 -
在调试模式下在 Visual Studio 中再次尝试,得到大致相同的结果。您分别调用
CompileToAssembly(),然后在注释掉该部分的情况下运行,对吗? -
我尝试运行 exe 现在结果更好了...不知道为什么我之前尝试它时会给出奇怪的结果。 Neway 的结果仍然与理论不匹配以下是 10000000 次迭代的结果: RegexOption.Compiled: 34413msCompiledToAssembly: 37125 Interpreted: 47322 .... 为什么遵守汇编比编译正则表达式花费更多时间??
-
我希望你在没有
CompileToAssembly();的情况下运行这个程序,否则程序集将被重新创建,并且一旦你调用DuplicatedString就必须再次jitted。从 Best Practices 我们了解到,程序集不是动态加载,而是与您的项目静态链接,即通过在预构建步骤中构建它,这一点很重要。