Shopify / measured

Encapsulate measurements and their units in Ruby and Ruby on Rails.
MIT License
362 stars 28 forks source link

Add defensive check to avoid unnecessary gsub #153

Closed bitwise-aiden closed 8 months ago

bitwise-aiden commented 8 months ago
image

When instantiating a large volume of Measurable objects gsub is run indiscriminately. I'm adding a defensive check as benchmarks show this is a lot faster.

bench.rb ```ruby require "benchmark/ips" class BenchGsub VALUES = 1000.times.map { |v| (v / 10).to_s } class << self def raw VALUES.each { |v| v.gsub(/\.0*\Z/, "") } end def check(value) VALUES.each { |v| v.gsub(/\.0*\Z/, "") if /\.0*\Z/.match?(v) } end end end Benchmark.ips do |x| x.report("raw", &BenchGsub.method(:raw)) x.report("check", &BenchGsub.method(:check)) x.compare! end ```
                 raw    71.000 i/100ms
               check   432.286B i/100ms
Calculating -------------------------------------
                 raw      3.405k (± 4.1%) i/s -     17.040k in   5.015206s
               check      3.948Q (± 4.1%) i/s -     19.628Q in   4.985779s

Comparison:
               check: 3947665236439899.5 i/s
                 raw:     3405.4 i/s - 1159229966836.24x  slower
bitwise-aiden commented 8 months ago

Nice! The way I read this code is it trims any .000 at the end. And it's faster to do that if we check for match? before hand.

Correct!

bitwise-aiden commented 8 months ago

This is good! Is .sub faster? Probably not. I've not measured it, but I suspect that we need gsub to remove all training 0.