Skip to content

ClassyEnum build method performance #59

@fxgallego

Description

@fxgallego

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
end

And 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
      end

This 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
      end

Thanks for this great gem! 😃

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions