我需要搜索违反“我们的数据中不使用社会安全号码”规则的人,并且需要知道以下两行之间是否存在性能差异(以及原因)。
感谢。
[0-9]{3}-[0-9]{2}-[0-9]{4}
VS
\d\d\d-\d\d-\d\d\d\d
请求的细节:
引擎:被删除以阻止标记混淆
答案 0 :(得分:9)
我认为你会发现性能差异微不足道。使用第一个,因为它一目了然更容易阅读。编译正则表达式后(如果您在将其用于重用之前进行编译),无论如何都无关紧要。
在需要进行优化之前,请勿进行优化。
答案 1 :(得分:8)
除了性能之外,我最近发现\ d和[0-9]不完全相同,因为there are more than just 10 digits。因此,第二版可能会产生更多的误报。
答案 2 :(得分:3)
性能差异(如果有的话)绝对可以忽略不计。您可能会优化应用程序的错误部分。
答案 3 :(得分:3)
性能差异应该可以忽略不计。在一个不相关的说明中,如果您正在处理的数据与我看到的内容类似,那么通过使破折号可选来扩展搜索可能很有用:
\b\d{3}-?\d{2}-?\d{4}\b
更新:好点,耿。字边界技巧非常有用,所以我肯定会在第一遍中包含它。
答案 4 :(得分:1)
与任何性能问题一样,答案是使用您自己的数据对其进行基准测试并找出答案。将结果与一些样本数据一起发布,因为这是一个很好的问题。
答案 5 :(得分:1)
这个Ruby脚本说第一个稍慢,但我认为任何引擎上的差异都可以忽略不计。
require 'benchmark'
include Benchmark
def random_ssn
format "%03d-%02d-%04d", rand(1000), rand(100), rand(10000)
end
bm do |x|
x.report("range") { 100_000.times { /[0-9]{3}-[0-9]{2}-[0-9]{4}/ =~ random_ssn } }
x.report("digit") { 100_000.times { /\d\d\d-\d\d-\d\d\d\d/ =~ random_ssn } }
end
结果:
user system total real
range 1.080000 0.030000 1.110000 ( 1.245579)
digit 0.980000 0.030000 1.010000 ( 1.149390)
答案 6 :(得分:1)
当然,这两个表达式的性能取决于您正在使用的正则表达式引擎的实现。差异应该很小,所以在将其视为瓶颈之前不要进行优化。
这是一个小小的性能比较,使用perl 5.8.3和8MB随机数据(数字,短划线,空格)的样本:
time perl -ne 'if (/\d\d\d-\d\d-\d\d\d\d/) {print "."}' < numbers.txt
[output omitted]
real 0m0.143s
user 0m0.136s
sys 0m0.007s
time perl -ne 'if (/[0-9]{3}-[0-9]{2}-[0-9]{4}/) {print "."}' < numbers.txt
[output omitted]
real 0m0.166s
user 0m0.160s
sys 0m0.006s
所以第一个实际上要快一点(这在几次调用中是一致的)。
答案 7 :(得分:1)
除了您注意到的内容之外,还有更好的优化:
Social security number cannot start from number greater than 772
这样可以立即减少您的匹配组,现在您可以:
[0-7][0-9]{2}-[0-9]{2}-[0-9]{4}
我想我想说的是,优化不一定只是技术性的。
修改强>
根据评论更改了正则表达式。谢谢大卫!
答案 8 :(得分:1)
补充说明这不太可能是性能瓶颈 - 与I / O等相比,差异不大可能是可衡量的。
话虽如此 - 如果您担心,请测量它,不要猜测。
答案 9 :(得分:1)
我刚刚在.NET中使用benchmark feature of Regex Hero进行了测试。
令人惊讶的是,第一个表达式更快,尽管只是略微如此。我对有效的社会安全号码执行了500,000次迭代,结果如下:
1.547秒 - [0-9] {3} - [0-9] {2} - [0-9] {4}
1.844秒 - \ d \ d \ d- \ d \ d- \ d \ d \ d \ d
我每次测试3次以确保基准测试准确。有趣的是,.NET中的结果与Ruby和Perl中的结果完全相反。