【问题标题】:Regex vs Tryparse what is the best in performance正则表达式 vs Tryparse 什么是最好的性能
【发布时间】:2011-08-08 13:58:48
【问题描述】:

在我的 ASP.net 项目中,我需要验证用户输入的一些基本数据类型。数据类型有数字、小数、日期时间等。

就性能而言,我应该采取的最佳方法是什么?是Regex.IsMatch()还是TryParse()做的?

提前致谢。

【问题讨论】:

  • 你真的在乎吗?与 asp.net 的其他所有方法相比,这两种方法中的任何一种在性能影响方面似乎都微不足道。
  • 使用(Ajax 控制工具)[ajaxcontroltoolkit.codeplex.com/] 并快乐。
  • 使用最合适/最容易维护的东西。在这种情况下,性能不是问题:)

标签: c# asp.net regex performance tryparse


【解决方案1】:

TryParseRegex.IsMatch 用于两个根本不同的事情。 Regex.IsMatch 告诉您所讨论的字符串是否与某些特定模式匹配。它返回一个是/否的答案。 TryParse 如果可能的话实际上会转换值,并告诉你它是否成功。

除非您在制作正则表达式时非常小心,否则Regex.IsMatch 可以返回true,而TryParse 将返回false。例如,考虑解析byte 的简单情况。使用TryParse,您有:

byte b;
bool isGood = byte.TryParse(myString, out b);

如果myString 中的值介于0 和255 之间,TryParse 将返回true

现在,让我们试试Regex.IsMatch。让我们看看,那个正则表达式应该是什么?我们不能只说@"\d+" 甚至@\d{1,3}"。指定格式成为一项非常困难的工作。您必须处理前导 0、前导和尾随空格,并允许 255 但不允许 256

这只是用于解析 3 位数字。当您解析 intlong 时,规则会变得更加复杂。

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

你最好尽可能使用TryParse,如果只是为了省去你想出一个可靠的正则表达式来进行验证的麻烦。很可能(我会说几乎可以肯定)任何本机类型的特定 TryParse 将比等效的正则表达式执行得更快。

上面说,我在这个答案上花费的时间可能比你的网页在整个生命周期中执行你的TryParseRegex.IsMatch--total 所花费的时间还要多。与您的网站所做的其他事情相比,执行这些事情的时间是如此之少,您花在思考问题上的任何时间都是浪费的。

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

【讨论】:

    【解决方案2】:

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

        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());
        }
    }
    

    【讨论】:

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

    不要试图让正则表达式做所有事情。

    有时,一个简单的正则表达式可以完成 90% 的工作,而要让它完成你需要的所有工作,复杂性会增加十倍或更多。

    然后我经常发现最简单的解决方案是使用正则表达式检查表单,然后依靠良好的旧代码进行值检查。

    以日期为例,使用正则表达式检查日期格式是否匹配,然后使用捕获组检查各个值的值。

    【讨论】:

      【解决方案4】:

      我猜 TryParse 更快,但更重要的是,它更具表现力。

      当您考虑所使用的每种数据类型的所有有效值时,正则表达式可能会变得非常难看。例如,对于 DateTime,您必须确保月份在 1 到 12 之间,并且日期在该特定月份的有效范围内。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-09
        • 1970-01-01
        • 1970-01-01
        • 2011-06-15
        • 2015-06-09
        相关资源
        最近更新 更多