为什么DateTime.Parse如此缓慢?

10

我对 DateTime.Parse 的速度有些震惊。 这段代码执行需要约100秒; 如果我使用正则表达式版本,它只需要100毫秒。 这是怎么回事?

Stopwatch sw = new Stopwatch();
sw.Start();
var re = new Regex(@"(\d\d)/(\d\d)/(\d\d\d\d) (\d\d):(\d\d):(\d\d)", RegexOptions.Compiled);
for (int i = 0; i < 100000; i++)
{
    //var m = re.Match("08/01/2012 23:10:12");
    DateTime.Parse("08/01/2012 23:10:12", CultureInfo.CreateSpecificCulture("en-US"));
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);

编辑:Mark是正确的,将CultureInfo.CreateSpecificCulture("en-US")从循环外部移动是有帮助的。我之前没有这样做的原因是我使用VS Profiler对这段代码进行了分析,并显示了以下结果:

输入图像描述

1个回答

30

这不是一个公平的测试。

  1. 调用 CultureInfo.CreateSpecificCulture("en-US") 是耗时的部分。将其移到循环外,将结果存储并重复使用。

  2. 你的正则表达式只处理一种特定格式,但 DateTime.Parse 可以处理许多不同的输入格式。它必须决定使用哪种它理解的格式才是正确的。如果您预先知道格式,则应使用 DateTime.ParseExact 而不是 DateTime.Parse

修正后的代码如下:

CultureInfo ci = CultureInfo.CreateSpecificCulture("en-US");
for (int i = 0; i < 100000; i++)
{
    DateTime.ParseExact("08/01/2012 23:10:12", "MM/dd/yyyy HH:mm:ss", ci);
}

通过这两个改变,我发现DateTime.ParseExact和正则表达式的方法几乎是相同的。

而且你的正则表达式接受一些无效的日期时间格式,比如00/00/0000 99:99:99。如果你修复它只接受有效的日期时间,它会变得更慢。


3
哦,我感觉好傻,将“CreateSpecificCulture”移出循环后性能得到了改善。之前我没有这么做是因为使用了VS Profiler,它显示问题在“Parse”中,参见编辑中的截图。 - Andrey
1
当然,我同意在这里使用正则表达式有点作弊,但是考虑到输入数据是有效的并且性能更重要,所以我考虑切换到它。 - Andrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接