RegEx.IsMatch() vs. String.ToUpper().Contains() performance

前端 未结 3 672
深忆病人
深忆病人 2020-12-11 19:47

Since there is no case insensitive string.Contains() (yet a case insensitive version of string.Equals() exists which baffles me, but I digress) in

相关标签:
3条回答
  • 2020-12-11 20:00

    I would expect RegEx.match to be slow based on personal experience with regular expression parsers in general. But as many folks have mentioned, profiling it is the best way to find out for sure. I've had to fix performance issues related to regular expression parsers, toLower and toUpper have never come back to bite me.

    0 讨论(0)
  • 2020-12-11 20:01

    There is another version using String.IndexOf(String,StringComparison) that might be more efficient than either of the two you suggested:

    string testString = "tHiSISaSTRINGwiThInconSISteNTcaPITaLIZATion";
    bool contained = testString.IndexOf("string", StringComparison.OrdinalIgnoreCase) >= 0;
    

    If you need a culture-sensitive comparison, use CurrentCultureIgnoreCase instead of OrdinalIgnoreCase.

    0 讨论(0)
  • 2020-12-11 20:17

    Here's a benchmark

    using System;
    using System.Diagnostics;
    using System.Text.RegularExpressions;
    
    public class Program
    {
        public static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();
    
            string testString = "tHiSISaSTRINGwiThInconSISteNTcaPITaLIZATion";
    
            sw.Start();
            var re = new Regex("string", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
            for (int i = 0; i < 1000000; i++)
            {
                bool containsString = re.IsMatch(testString);
            }
            sw.Stop();
            Console.WriteLine("RX: " + sw.ElapsedMilliseconds);
    
            sw.Restart();
            for (int i = 0; i < 1000000; i++)
            {
                bool containsStringRegEx = testString.ToUpper().Contains("STRING");
            }
    
    
            sw.Stop();
            Console.WriteLine("Contains: " + sw.ElapsedMilliseconds);
    
            sw.Restart();
            for (int i = 0; i < 1000000; i++)
            {
                bool containsStringRegEx = testString.IndexOf("STRING", StringComparison.OrdinalIgnoreCase) >= 0 ;
            }
    
    
            sw.Stop();
            Console.WriteLine("IndexOf: " + sw.ElapsedMilliseconds);
        }
    }
    

    Results were

    IndexOf (183ms) > Contains (400ms) > Regex (477ms)

    (Updated output times using the compiled Regex)

    0 讨论(0)
提交回复
热议问题