ผมได้แสดงความคิดเห็นเมื่อวานนี้ในคำตอบที่มีคนใช้[0123456789]
ในการแสดงออกปกติมากกว่าหรือ[0-9]
\d
ฉันบอกว่ามันอาจจะมีประสิทธิภาพมากกว่าในการใช้ตัวระบุช่วงหรือตัวเลขมากกว่าชุดอักขระ
ฉันตัดสินใจที่จะทดสอบในวันนี้และพบกับความประหลาดใจของฉันที่ (ใน C # regex engine อย่างน้อย) \d
ดูเหมือนว่าจะมีประสิทธิภาพน้อยกว่าอีกสองอันที่ดูเหมือนจะไม่แตกต่างกันมากนัก นี่คือผลการทดสอบของฉันมากกว่า 10,000 สายสุ่ม 1,000 ตัวอักษรแบบสุ่มกับ 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;
}
}
}
\d
ไม่ได้หมายถึงสิ่งเดียวกันในภาษาต่าง ๆ ใน Java ตัวอย่างเช่น\d
ตรงกับ 0-9 เท่านั้น
\d
เกี่ยวข้องกับสถานที่ เช่นฮีบรูใช้ตัวอักษรเป็นตัวเลข