-
Notifications
You must be signed in to change notification settings - Fork 26
Description
I was profiling some code in my app and found that build method is based on find method to search the Enum that comes from the database.
In my case, one of the enums has 14 different types, and for a specific use case where I instantiate about 2000 records from the database, each one with several classy_enum fields the current implementation is noticeable slow.
I implemented an additional find method only to use it in a benchmark. I'm not suggesting replacing the current implementation with this. It´s only used as POC.
class ClassyEnum::Base
def self.find_fast(key = nil)
@@found ||= Hash.new
@@found[key] ||= begin
if block_given?
find(key, &block)
else
find { |e| e.to_s == key.to_s }
end
end
end
endAnd then run a benchmark:
Warming up --------------------------------------
find 5.548k i/100ms
find_fast 247.291k i/100ms
Calculating -------------------------------------
find 57.654k (± 1.6%) i/s - 288.496k in 5.005099s
find_fast 2.509M (± 3.9%) i/s - 12.612M in 5.036393s
Comparison:
find_fast: 2508639.9 i/s
find: 57654.4 i/s - 43.51x (± 0.00) slower
I think that something like this is a huge improvement and also saves a lot of cpu cycles.
Also, in the current implementation, I think there is a map call that can be removed
def find(key=nil)
if block_given?
super
elsif map(&:to_s).include? key.to_s
super { |e| e.to_s == key.to_s }
end
endThis is the same, no need to map and test for include?, or maybe I don't know something
def find(key=nil)
if block_given?
super
else
super { |e| e.to_s == key.to_s }
end
endThanks for this great gem! 😃