我昨天对一个答案发表了评论,其中有人在正则表达式中使用了[0123456789]
,而不是[0-9]
或\d
。我说使用范围或数字说明符可能比使用字符集更快。
我决定今天测试一下,并惊讶地发现(至少在C#regex引擎中)\d
似乎比其他两个似乎没有太大区别的任何一个都慢。这是我的测试输出超过10000个随机字符串,其中包含1000个随机字符,其中5077个实际上包含一个数字:
Regex \d took 00:00:00.2141226 result: 5077/10000
Regex [0-9] took 00:00:00.1357972 result: 5077/10000 63.42 % of first
Regex [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 1 char 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”是否表示数字?:
< code>[0-9]不等同于< code>\d。< code>[0-9]仅匹配< code>0123456789字符,而< code>\d匹配< code>[0-9]和其他数字字符,例如东方阿拉伯数字٠١٢٣٤٥٦٧٨٩
感谢ByteBlast在文档中注意到了这一点。只需更改正则表达式构造函数:
var rex = new Regex(regex, RegexOptions.ECMAScript);
给出新的计时:
Regex \d took 00:00:00.1355787 result: 5077/10000
Regex [0-9] took 00:00:00.1360403 result: 5077/10000 100.34 % of first
Regex [0123456789] took 00:00:00.1362112 result: 5077/10000 100.47 % of first
< code>\d检查所有Unicode数字,而< code>[0-9]仅限于这10个字符。例如,波斯语数字۱۲۳۴۵۶۷۸۹
是与< code>\d匹配的Unicode数字的一个例子,但不与< code>[0-9]匹配。
您可以使用以下代码生成所有此类字符的列表:
var sb = new StringBuilder();
for(UInt16 i = 0; i < UInt16.MaxValue; i++)
{
string str = Convert.ToChar(i).ToString();
if (Regex.IsMatch(str, @"\d"))
sb.Append(str);
}
Console.WriteLine(sb.ToString());
产生:
0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९০১২৩৪৫৬৭৮৯੦੧੨੩੪੫੬੭੮੯૦૧૨૩૪૫૬૭૮૯୦୧୨୩୪୫୬୭୮୯௦௧௨௩௪௫௬௭௮௯౦౧౨౩౪౫౬౭౮౯೦೧೨೩೪೫೬೭೮೯൦൧൨൩൪൫൬൭൮൯๐๑๒๓๔๕๖๗๘๙໐໑໒໓໔໕໖໗໘໙༠༡༢༣༤༥༦༧༨༩၀၁၂၃၄၅၆၇၈၉႐႑႒႓႔႕႖႗႘႙០១២៣៤៥៦៧៨៩᠐᠑᠒᠓᠔᠕᠖᠗᠘᠙᥆᥇᥈᥉᥊᥋᥌᥍᥎᥏᧐᧑᧒᧓᧔᧕᧖᧗᧘᧙᭐᭑᭒᭓᭔᭕᭖᭗᭘᭙᮰᮱᮲᮳᮴᮵᮶᮷᮸᮹᱀᱁᱂᱃᱄᱅᱆᱇᱈᱉᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙꘠꘡꘢꘣꘤꘥꘦꘧꘨꘩꣐꣑꣒꣓꣔꣕꣖꣗꣘꣙꤀꤁꤂꤃꤄꤅꤆꤇꤈꤉꩐꩑꩒꩓꩔꩕꩖꩗꩘꩙0123456789
今天我决定测试一下,结果我惊讶地发现(至少在C#正则表达式引擎中)似乎比其他两个没有太大区别的代码效率要低。下面是我测试输出的10000个由1000个随机字符组成的字符串,其中5077个实际包含一个数字: 这对我来说是一个惊喜,有两个原因,如果有人能给我一些启示,我会很感兴趣: 我本以为范围的实现会比集合的实现效率高得多。 我不能理解为什么比差。除了的简写之外,还有其他内容吗? 下面是测试代码:
问题内容: 我试图实施Miller- Rabin素数测试 ,并且对为什么中型数字(〜7位数字)花费如此长时间(> 20秒)感到困惑。我最终发现以下代码行是问题的根源: (其中,和都是相似的,但不相等的中号,是幂运算符,并且是模运算符) 然后,我尝试将其替换为以下内容: 相比之下,它几乎是瞬时的。 对于上下文,这是原始功能: 定时计算示例: 输出(与PyPy 1.9.0一起运行): 输出(在Pyth
问题内容: 为什么比Java 慢?换句话说,为什么优于? 当我查看中的实现时,速度似乎应该是相同的: ArrayList.size() ArrayList.isEmpty() 如果我们只编写一个简单的程序来获取两种方法所花费的时间,那么在所有情况下这种情况都将花费更多,为什么会这样呢? 这是我的TestCode; 在所有情况下都在这里。为什么? 问题答案: 您的测试代码有缺陷。 只需颠倒顺序,即先
问题内容: 我正在学习Go,并且一直沉迷于Go旅游(exercise- stringer.go:https : //tour.golang.org/methods/7)。 这是一些代码: 所以我想出了is 的内部表示,所以散布算子起作用了。但我得到: 有没有搞错?字符串切片也不起作用,这是怎么回事? 编辑 :对不起,我的问题中有一个错误- 错误是关于type的,不是。我在玩代码,并且粘贴了错误的输
问题内容: 我在进行一些MySQL测试查询,并意识到将字符串列与(作为数字)进行比较可以得出! 但是,将其与其他任何数字(正数或负数,整数或十进制数)进行比较,将得到预期的结果(当然,除非字符串是数字以字符串的形式表示) 当然,按预期将字符串与as字符串进行比较会得出false。 但是,为什么它如此呢? 这是为什么? 问题答案: MySQL自动将字符串转换为数字: 不以数字开头的字符串的值为0:
问题内容: 我必须编写一个例程,如果变量的类型为,则将变量的值加1,否则将变量的值分配为0,其中变量的初始值为或。 第一个实现是因为我认为没有数字会使算术表达式为假,但是由于计算为真,所以这是错误的。然后,我得知行为类似于0,并且以下表达式均被评估为true。 当然不是0。被评估为false。这使看似重言式的表达成为错误。 为什么实际上不是0,却像0? 问题答案: 您真正的问题似乎是: 为什么: