Вчера я сделал комментарий, где кто-то использовал [0123456789] в регулярном выражении, а не [0-9] или \d. Я сказал, что, вероятно, более эффективно использовать спецификатор диапазона или цифры, чем набор символов.
Я решил проверить это сегодня и, с удивлением обнаружил, что (по крайней мере, в двигателе с регулярным выражением С#) \d оказывается менее эффективным, чем любой из двух других, которые, похоже, не сильно отличаются друг от друга. Вот мой тестовый вывод более 10000 случайных строк из 1000 случайных символов с 5077, фактически содержащим цифру:
Regular expression \d           took 00:00:00.2141226 result: 5077/10000
Regular expression [0-9]        took 00:00:00.1357972 result: 5077/10000  63.42 % of first
Regular expression [0123456789] took 00:00:00.1388997 result: 5077/10000  64.87 % of first
Это сюрприз для меня по двум причинам:
- Я бы подумал, что диапазон будет реализован намного эффективнее, чем набор.
-  Я не понимаю, почему \dхуже, чем[0-9]. Есть ли больше\d, чем просто сокращение для[0-9]?
Вот тестовый код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace SO_RegexPerformance
{
    class Program
    {
        static void Main(string[] args)
        {
            var rand = new Random(1234);
            var strings = new List<string>();
            //10K random strings
            for (var i = 0; i < 10000; i++)
            {
                //Generate random string
                var sb = new StringBuilder();
                for (var c = 0; c < 1000; c++)
                {
                    //Add a-z randomly
                    sb.Append((char)('a' + rand.Next(26)));
                }
                //In roughly 50% of them, put a digit
                if (rand.Next(2) == 0)
                {
                    //Replace one character with a digit, 0-9
                    sb[rand.Next(sb.Length)] = (char)('0' + rand.Next(10));
                }
                strings.Add(sb.ToString());
            }
            var baseTime = testPerfomance(strings, @"\d");
            Console.WriteLine();
            var testTime = testPerfomance(strings, "[0-9]");
            Console.WriteLine("  {0:P2} of first", testTime.TotalMilliseconds / baseTime.TotalMilliseconds);
            testTime = testPerfomance(strings, "[0123456789]");
            Console.WriteLine("  {0:P2} of first", testTime.TotalMilliseconds / baseTime.TotalMilliseconds);
        }
        private static TimeSpan testPerfomance(List<string> strings, string regex)
        {
            var sw = new Stopwatch();
            int successes = 0;
            var rex = new Regex(regex);
            sw.Start();
            foreach (var str in strings)
            {
                if (rex.Match(str).Success)
                {
                    successes++;
                }
            }
            sw.Stop();
            Console.Write("Regex {0,-12} took {1} result: {2}/{3}", regex, sw.Elapsed, successes, strings.Count);
            return sw.Elapsed;
        }
    }
}
