FriendlyId uses Rails's extending method to avoid overwriting your model's find
method. Internally this is implemented similar to this:
def self.friendly
all.extending(friendly_id_config.finder_methods)
end
This however comes with a performance impact, because extending
invokes Ruby's extend
, which blows away MRI's method cache. To work around this, FriendlyId lets you include a :finders
module which overrides your model's find
to increase performance.
As of Ruby 2.1 though, extend
only blows away the current classes' method cache. Behold the difference:
Using ruby 2.0.0 AR 4.0.2 with sqlite3 (in-memory)
user system total real
find (in-table slug) 0.820000 0.000000 0.820000 ( 0.837980)
find (in-table slug; using finders module) 0.390000 0.000000 0.390000 ( 0.408671)
------------------------------------------------------------------------
Using ruby 2.1.0 AR 4.0.2 with sqlite3 (in-memory)
user system total real
find (in-table slug) 0.480000 0.000000 0.480000 ( 0.491496)
find (in-table slug; using finders module) 0.400000 0.010000 0.410000 ( 0.398222)
While you still incur some cost for invoking extend
, it's much, much cheaper in 2.1 than in previous versions.