Regex vs Tryparse性能最佳

Tha*_*hka 7 c# regex asp.net performance tryparse

在我的ASP.net项目中,我需要为用户输入验证一些基本数据类型.数据类型类似于数字,小数,日期等.

在性能方面我应该采取的最佳方法是什么?它是通过做Regex.IsMatch()TryParse()

提前致谢.

Jim*_*hel 9

TryParseRegex.IsMatch用于两个根本不同的东西.Regex.IsMatch告诉您相关字符串是否与某个特定模式匹配.它返回是/否答案.TryParse实际上,如果可能,转换值,并告诉您它是否成功.

除非你在制作正则表达式时非常小心,否则Regex.IsMatch返回trueTryParse会返回false.例如,考虑解析a的简单情况byte.随TryParse你而来:

byte b;
bool isGood = byte.TryParse(myString, out b);
Run Code Online (Sandbox Code Playgroud)

如果值in myString介于0和255之间,TryParse则返回true.

现在,让我们试试吧Regex.IsMatch.让我们看看,正则表达式应该是什么?我们不能只说@"\d+"或甚至@\d{1,3}".指定格式变得非常困难.你必须处理前导0,前导和尾随空格,允许255但不允许256.

这仅仅是为了解析一个3位数字.当你解析一个int或那个时,规则变得更加复杂long.

正则表达式非常适合确定表单.在确定价值方面,他们很糟糕.由于我们的标准数据类型都有限制,因此确定其值是确定数字是否有效的一部分.

你最好TryParse尽可能地使用它,如果只是为了省去尝试提出一个可靠的正则表达式进行验证的头痛.很可能(我会说几乎可以肯定),TryParse任何本机类型的特定执行速度都比同等正则表达式快.

上面说了,我大概花了更多的时间在这个答案比你的网页将花费执行你TryParseRegex.IsMatch--total其整个生命.在网站正在做的其他事情的背景下,执行这些事情的时间非常少,任何时候你花费在思考问题上都会浪费.

TryParse如果可以,请使用,因为它更容易.否则使用Regex.


Bru*_*uno 6

正如其他人所说,回答这个问题的最佳方法是衡量它;)

    static void Main(string[] args)
    {

        List<double> meansFailedTryParse = new List<double>();
        List<double> meansFailedRegEx = new List<double>();
        List<double> meansSuccessTryParse = new List<double>();
        List<double> meansSuccessRegEx = new List<double>();


        for (int i = 0; i < 1000; i++)
        {


            string input = "123abc";

            int res;
            bool res2;
            var sw = Stopwatch.StartNew();
            res2 = Int32.TryParse(input, out res);
            sw.Stop();
            meansFailedTryParse.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + " try parse :" + sw.Elapsed.TotalMilliseconds);

            sw = Stopwatch.StartNew();
            res2 = Regex.IsMatch(input, @"^[0-9]*$");
            sw.Stop();
            meansFailedRegEx.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + "  Regex.IsMatch :" + sw.Elapsed.TotalMilliseconds);

            input = "123";
            sw = Stopwatch.StartNew();
            res2 = Int32.TryParse(input, out res);
            sw.Stop();
            meansSuccessTryParse.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + " try parse :" + sw.Elapsed.TotalMilliseconds);


            sw = Stopwatch.StartNew();
            res2 = Regex.IsMatch(input, @"^[0-9]*$");
            sw.Stop();
            meansSuccessRegEx.Add(sw.Elapsed.TotalMilliseconds);
            //Console.WriteLine("Result of " + res2 + "  Regex.IsMatch :" + sw.Elapsed.TotalMilliseconds);
        }

        Console.WriteLine("Failed TryParse mean execution time     " + meansFailedTryParse.Average());
        Console.WriteLine("Failed Regex mean execution time        " + meansFailedRegEx.Average());

        Console.WriteLine("successful TryParse mean execution time " + meansSuccessTryParse.Average());
        Console.WriteLine("successful Regex mean execution time    " + meansSuccessRegEx.Average());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • tl;dr 对于那些真正需要答案的人:`int.TryParse()` 总是比 `Regex.IsMatch()` 快(高达一个数量级)。它也比使用“RegexOptions.Compiled”构造的 Regex 对象更快。确保根据您的数字的长度使用适当的类(例如`ulong`),并记住`decimal.TryParse()` 比`int.TryParse()` 慢得多。如果这些都不适合你,`stringVariable.All(char.IsDigit)` 在性能方面提供了一个可以接受的中间立场,它也很简洁。 (7认同)