Есть ли разница в производительности в этих двух поисках номера социального страхования? - PullRequest
2 голосов
/ 18 февраля 2009

Мне нужно выполнить поиск людей, которые нарушают наше правило «не использовать номера социального страхования в своих данных» и должны знать, есть ли различия в производительности (и почему) между двумя строками ниже.

Спасибо.

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

против

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


Запрашиваемая информация:
двигатель: удален, чтобы избежать путаницы в тегах

Ответы [ 10 ]

9 голосов
/ 18 февраля 2009

Я думаю, вы увидите очень незначительные различия в производительности. Используйте первый, так как его легче читать с первого взгляда. Как только Regex скомпилирован (если вы компилируете его перед использованием в целях повторного использования), это все равно не будет иметь значения.

Не оптимизируйте, пока не потребуется для оптимизации.

8 голосов
/ 18 февраля 2009

Помимо производительности, я недавно обнаружил, что \ d и [0-9] не идентичны, потому что - это более 10 цифр . Поэтому вторая версия может дать больше ложных срабатываний.

3 голосов
/ 18 февраля 2009

Разница в производительности должна быть незначительной. На несвязанной ноте, если данные, с которыми вы имеете дело, похожи на то, что я вижу, возможно, было бы полезно расширить поиск, сделав дополнительные тире:

\b\d{3}-?\d{2}-?\d{4}\b

Обновление: Хороший вопрос, Кенг. Трюк с ограничением слов действительно полезен, поэтому я определенно включил бы его в первый проход.

3 голосов
/ 18 февраля 2009

Разница в производительности, если таковая имеется, будет абсолютно незначительной. Скорее всего, вы оптимизируете не ту часть вашего приложения.

1 голос
/ 15 августа 2009

Я только что проверил это в .NET с помощью функции в Regex Hero .

.

Удивительно, но первое выражение быстрее, хотя и незначительно. Я выполнил 500 000 итераций с действительным номером социального страхования, и вот результаты:

1,574 секунды - [0-9] {3} - [0-9] {2} - [0-9] {4}

1,844 секунды - \ d \ d \ d- \ d \ d- \ d \ d \ d \ d

Я проверил каждый из них 3 раза, чтобы убедиться, что тест был точным. Забавно, что результат в .NET является полной противоположностью результатов в Ruby и Perl.

1 голос
/ 18 февраля 2009

После комментария о том, что это, скорее всего, не является узким местом в производительности - по сравнению с вводом / выводом и т. Д. Разница вряд ли будет измеримой.

Сказав это - если вы обеспокоены, измерьте это, не угадайте.

1 голос
/ 18 февраля 2009

Есть лучшая оптимизация, кроме того, что вы заметили:

Номер социального страхования не может начинаться с номера больше 772

Чтобы мгновенно сократить группу совпадений, теперь вы можете:

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

Полагаю, я пытаюсь сказать, что оптимизация не должна быть просто технической.

EDIT

Изменено регулярное выражение в соответствии с комментарием. Спасибо Дэвид!

1 голос
/ 18 февраля 2009

Конечно, производительность двух выражений зависит от реализации используемого вами механизма регулярных выражений. Разница должна быть небольшой, поэтому не оптимизируйте, пока не увидите, что это узкое место.

Вот небольшое сравнение производительности с использованием Perl 5.8.3 и выборки из 8 МБ случайных данных (цифры, тире, пробелы):

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

Итак, первый на самом деле чуть-чуть быстрее (это согласуется для нескольких вызовов).

1 голос
/ 18 февраля 2009

Этот скрипт на 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)
1 голос
/ 18 февраля 2009

Как и в случае с любым вопросом о производительности, ответ заключается в том, чтобы протестировать его на своих собственных данных и выяснить. Опубликуйте результаты с некоторыми примерами данных, потому что это хороший вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...