Saya membuat komentar kemarin pada jawaban di mana seseorang telah digunakan [0123456789]
dalam ekspresi reguler daripada [0-9]
atau \d
. Saya mengatakan mungkin lebih efisien menggunakan rentang atau digit specifier daripada set karakter.
Saya memutuskan untuk mengujinya hari ini dan mengejutkan saya bahwa (di mesin C # regex setidaknya) \d
tampaknya kurang efisien daripada salah satu dari dua lainnya yang tampaknya tidak jauh berbeda. Berikut ini adalah hasil pengujian saya lebih dari 10.000 string acak 1000 karakter acak dengan 5077 sebenarnya mengandung digit:
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
Ini mengejutkan saya karena dua alasan:
- Saya akan berpikir jangkauan akan diimplementasikan jauh lebih efisien daripada yang ditetapkan.
- Saya tidak mengerti mengapa
\d
lebih buruk dari itu[0-9]
. Apakah ada lebih\d
dari sekadar singkatan[0-9]
?
Ini adalah kode tes:
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;
}
}
}
\d
tidak berarti hal yang sama dalam berbagai bahasa. Di Jawa, misalnya \d
memang hanya cocok dengan 0-9
\d
berurusan dengan lokal. Misalnya bahasa Ibrani menggunakan huruf untuk angka.