lotus/utils — pull request #29 by KillaPL (2014-09-18 13:43:33+00:00)
Title: Don't bind blocks if not necessary

Binding a block is a performance drawback, replacing blk.call with yield improves performance drastically:

require 'lotus/view'
require 'benchmark/ips'

module Lotus
module Utils
class String
TOKENIZE_REGEXP = /\((.*)\)/
def fast_tokenize
if match = TOKENIZE_REGEXP.match(@string)
pre, post = match.pre_match, match.post_match
tokens = match[1].split(TOKENIZE_SEPARATOR)
tokens.each do |token|
yield(self.class.new("#{pre}#{token}#{post}"))
end
else
yield(self.class.new(@string))
end

nil
end
end
end
end

string = Lotus::Utils::String.new 'Lotus::(Utils|App)'

Benchmark.ips do |x|
x.report("blk.call") do
string.tokenize do |token|
token
end
end
x.report("yield") do
string.fast_tokenize do |token|
token
end
end
end

Results:

Calculating -------------------------------------
blk.call 10818 i/100ms
yield 62064 i/100ms
-------------------------------------------------
blk.call 127886.5 (±1.7%) i/s - 649080 in 5.076903s
yield 1091772.8 (±1.5%) i/s - 5461632 in 5.003712s