Оптимизация одного скрипта
Руби дарит нам радость, а взамен жрет память и CPU. Руководствуясь этим тезисом, оптимизирую руби код очень редко. Однако недавно столкнулся в любопытной штукой, когда изменение в одной строчки уменьшило время выполнения c 10 секунд до долей секунды.
У нас есть набор скриптов, которые запускаем вручную для проверки целостности различных параметров инфраструктуры, и там есть примерно такая строчка, которая выполняется навскидку 60 тысяч раз за один прогон:
... if string =~ /#{name}-\d{4}-\d{2}-\d{2}__\d{2}_\d{2}_\d{2}/
Оказалось что создавать регексп на лету - весьма и весьма медленно, лучше создать его один раз и использовать столько раз, сколько надо:
RE = /#{name}-\d{4}-\d{2}-\d{2}__\d{2}_\d{2}_\d{2}/
# ...
... if string =~ RE
Простой бенчмарк показывает, что разница по времени исполнения почти в два порядка, причем в важном для комфорта диапазоне:
require 'benchmark'
c = 60_000
name = "head"
re = /#{name}-tail-\d{4}-\d{2}/
string = "head-tail-2012-12"
i = 0
Benchmark.bm do |bm|
bm.report { c.times { i += 1 if string =~ /#{name}-tail-\d{4}-\d{2}/ } }
bm.report { c.times { i += 1 if string =~ /#{name}-tail-\d{4}/ } }
bm.report { c.times { i += 1 if string =~ /#{name}-tail/ } }
bm.report { c.times { i += 1 if string =~ re } }
end
puts "i: #{i}"
# user system total real
# 1.340000 0.020000 1.360000 ( 1.373314)
# 0.820000 0.010000 0.830000 ( 0.843216)
# 0.390000 0.020000 0.410000 ( 0.406644)
# 0.020000 0.000000 0.020000 ( 0.035978)
# i: 240000
Так что обычно на руби можно писать как угодно, но иногда нельзя.
Tweet