Когда я все время писал код на Perl, я использовал регулярные выражения для манипуляций со строками.Затем однажды я захотел создать некоторый код для поиска и анализа строкового содержимого и написал тест для сравнения некоторых регулярных выражений и стандартных поисков на основе индекса строки.Поиск по индексу отбросил регулярное выражение.Это не так сложно, но иногда мы не нуждаемся в сложностях при работе с простыми задачами.
Вместо того, чтобы мгновенно получить регулярное выражение, String.squeeze(' ')
может справиться со сжатием повторяющихся пробелов намного быстрее.Рассмотрим результаты теста производительности:
#!/usr/bin/env ruby
require 'benchmark'
asdf = 'There is a lot of white space.'
asdf.squeeze(' ') # => "There is a lot of white space."
asdf.gsub(/ +/, ' ') # => "There is a lot of white space."
asdf.gsub(/ {2,}/, ' ') # => "There is a lot of white space."
asdf.gsub(/\s\s+/, ' ') # => "There is a lot of white space."
asdf.gsub(/\s{2,}/, ' ') # => "There is a lot of white space."
n = 500000
Benchmark.bm(8) do |x|
x.report('squeeze:') { n.times{ asdf.squeeze(' ') } }
x.report('gsub1:') { n.times{ asdf.gsub(/ +/, ' ') } }
x.report('gsub2:') { n.times{ asdf.gsub(/ {2,}/, ' ') } }
x.report('gsub3:') { n.times{ asdf.gsub(/\s\s+/, ' ') } }
x.report('gsub4:') { n.times{ asdf.gsub(/\s{2,}/, ' ') } }
end
puts
puts "long strings"
n = 1000
str_x = 1000
Benchmark.bm(8) do |x|
x.report('squeeze:') { n.times{(asdf * str_x).squeeze(' ') }}
x.report('gsub1:') { n.times{(asdf * str_x).gsub(/ +/, ' ') }}
x.report('gsub2:') { n.times{(asdf * str_x).gsub(/ {2,}/, ' ') }}
x.report('gsub3:') { n.times{(asdf * str_x).gsub(/\s\s+/, ' ') }}
x.report('gsub4:') { n.times{(asdf * str_x).gsub(/\s{2,}/, ' ') }}
end
# >> user system total real
# >> squeeze: 1.050000 0.000000 1.050000 ( 1.055833)
# >> gsub1: 3.700000 0.020000 3.720000 ( 3.731957)
# >> gsub2: 3.960000 0.010000 3.970000 ( 3.980328)
# >> gsub3: 4.520000 0.020000 4.540000 ( 4.549919)
# >> gsub4: 4.840000 0.010000 4.850000 ( 4.860474)
# >>
# >> long strings
# >> user system total real
# >> squeeze: 0.310000 0.180000 0.490000 ( 0.485224)
# >> gsub1: 3.420000 0.130000 3.550000 ( 3.554505)
# >> gsub2: 3.850000 0.120000 3.970000 ( 3.974213)
# >> gsub3: 4.880000 0.130000 5.010000 ( 5.015750)
# >> gsub4: 5.310000 0.150000 5.460000 ( 5.461797)
Тесты основаны на том, чтобы squeeze(' ')
или gsub()
убрали дублированные пробелы.Как я и ожидал, сжатие ('') удаляет регулярное выражение.Регулярные выражения, использующие символ пробела, работают быстрее, чем эквивалентный шаблон, использующий \s
.
Конечно, регулярное выражение более гибкое, но размышления о том, нужно ли регулярное выражение, могут существенно повлиять на скорость обработки вашего кода.