![]() |
1
10
表达
我的理由是:
下面是在.NET中测试时每秒获得的迭代次数(不带RegexOptions.Compiled): Regex 100% valid input 50% valid input 100% invalid input "^[0-9]{1,2}$" 749086 800313 870748 "^[0-9]?[0-9]$" 731951 725984 740152 "^(?:[0-9]|([0-9][0-9]))$" 564654 687248 870378 使用RegexOptions。编译: Regex 100% valid input 50% valid input 100% invalid input "^[0-9]{1,2}$" 1486212 1592535 1831843 "^[0-9]?[0-9]$" 1301557 1448812 1559193 "^(?:[0-9]|([0-9][0-9]))$" 1131179 1303213 1394146 作为图表:
注意:我修改了每个正则表达式以要求精确匹配,而不是执行搜索。 |
![]() |
2
7
至少 理论上 ,像这样相同的正则表达式将产生相同的自动机。基于DFA的匹配器将一次匹配一个字符,并在其状态中编码不同的可能分支(而不是一次获取一个分支,然后在失败时回溯),因此每个分支的性能将相同。 所有三个正则表达式都将与此DFA匹配:
A州
:开始状态。如果看到一个数字,则转到B,否则转到错误状态。
这是我的语言理论答案。我无法与现实世界的regex引擎实现对话。我忽略了括号的捕获语义,因为我猜这不是问题的重点。自动机也不处理其他“非理论”的结构,如贪婪,展望等,至少在他们的教科书演示。 |
![]() |
3
4
如果不知道regex引擎,我们甚至无法决定这些是否正确。
例如,POSIX ERE是最长的最左边,而不是最长的最左边,因此它将在一系列备选方案中选择最长的,并因此选择一个字符串匹配
下一个问题是相同模式的捕获组。如果它们是故意的,那么它们是奇怪的,因为您保留的是两位数字,而不是一位数字。其他的模式并没有做到这一点,但据说它们在行为上是相同的。所以我要假设他们在这里是错误的。否则,捕获组的内存使用当然会比存储所需的成本更高 不 这样做。
下一个问题是没有任何锚。同样,我们也不知道这些是否正确,因为我们不清楚输入集是什么样子的,也不清楚特定引擎使用未编排的模式做什么。大多数引擎都会搜索字符串中的所有位置,但一些不太友好的引擎会在字符串中添加行首(BOL)和行尾(EOL)锚。在更为常用的引擎中,如果不发生这种情况,则行中间的邮政编码也将匹配,因为五位数字显然包含一位和两位数字的子字符串。你是否愿意
所以我得在这里做些猜测。我将关闭锚,但我将重新排序第三个版本分支,因为否则你永远无法匹配一个两位数的正常(非POSIX)类型的回溯NFAs大多数事情运行。 在考虑时机之前,看看regex编译器是用这些模式构建什么样的程序是值得的。
查看编译的模式确实是个好主意。观察正在执行的编译模式会更有指导意义。这两个都要注意:
编译器得到了 真聪明 在我们身上,把它编译成一个ahocarasick-trie结构。显然,这将执行完全不同于正常的回溯NFA将对同一个程序。 不管怎样,这里是你的模式的时间,或接近他们。我为第二个添加了一个替代公式,并且我交换了第三个的替代顺序。
这是由这个节目制作的:
以下是添加了锚的数字:
下面是生成第二组数字的最小修改程序:
|
![]() |
4
3
如果其中一个必须更快(可能取决于使用的regex引擎),那么在我看来,很明显第一个(可以是一个简单的Morris Pratt表DFA,与其他两个相反),因为其他两个可能需要回溯或执行额外的工作:
|
![]() |
5
3
我不知道内部结构,但一些假板凳怎么办?:天 蟒蛇
以秒为单位的结果
JavaScript
以秒为单位的结果
我们学到了什么?好吧,蟒蛇似乎是相当慢,V8似乎是相当快。
更新:Java版本
以秒为单位的结果(第4次运行的次数)
|
![]() |
6
1
那些正则表达式太小了,应该没关系。但是,如果我必须选择一个更有效的实现,它可能是[0-9]{1,2}或者[0-9][0-9]?,这不在您的选择范围内,因为不需要回溯。 |
![]() |
7
1
就像C和
(异常:如果启用了带圆括号的子表达式标记,则第三个显然会编译为包含额外的标记信息。) |
![]() |
S. Jacson · 任意两台发电机的速度差(内置功能) 2 年前 |
![]() |
Sadeq Dousti · 相当于“嵌套删除”的执行性能SQL查询 2 年前 |
![]() |
Prince · 复制大型文件需要更多时间 2 年前 |
![]() |
Sagar · 为什么在循环之外声明变量会更快? 2 年前 |
![]() |
seco · 如何在不挂起页面的情况下加载JS 2 年前 |