这两个社会安全号码搜索是否有性能差异?

时间:2009-02-18 14:54:29

标签: regex performance

我需要搜索违反“我们的数据中不使用社会安全号码”规则的人,并且需要知道以下两行之间是否存在性能差异(以及原因)。

感谢。

[0-9]{3}-[0-9]{2}-[0-9]{4}

VS

\d\d\d-\d\d-\d\d\d\d


请求的细节:
引擎:被删除以阻止标记混淆

10 个答案:

答案 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中的结果完全相反。