Currently, delegatable? call private_methods to check method is private or not. The private_methods generates an Array of methods per call. So a method call via delegate_all generates an extra Array every time.
This patch use private_method_defined? instead of private_methods. This reduce the extra Array.
The inherit argument for private_method_defined? is supported since Ruby 2.6.
So this patch only works for >= Ruby 2.6. Rubies old than Ruby 2.6 keep using private_methods.
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "activerecord"
gem "sqlite3"
if ENV["USE_FORKED_GEM"]
gem "draper", github: "y-yagi/draper", branch: "improve-delegate_all-performance"
else
gem "draper"
end
gem "benchmark-ips"
end
require "active_record"
require "logger"
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = nil
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string :name, null: false
t.timestamps
end
end
ActiveRecord::Base.logger = Logger.new(STDOUT)
class User < ActiveRecord::Base
end
class UserDecorator < Draper::Decorator
delegate_all
def decorated_name
"'#{name}'"
end
end
User.create!(name: "Dummy User")
u = UserDecorator.decorate(User.first)
Benchmark.ips do |x|
x.report(ENV["USE_FORKED_GEM"] == "true" ? "forked draper" : "released draper") do
1000.times { u.decorated_name }
end
x.save! ENV["SAVE_FILE"] if ENV["SAVE_FILE"]
x.compare!
end
Description
Currently,
delegatable?
callprivate_methods
to check method is private or not. Theprivate_methods
generates an Array of methods per call. So a method call viadelegate_all
generates an extra Array every time.This patch use
private_method_defined?
instead ofprivate_methods
. This reduce the extra Array.The inherit argument for
private_method_defined?
is supported since Ruby 2.6. So this patch only works for >= Ruby 2.6. Rubies old than Ruby 2.6 keep usingprivate_methods
.Ref: https://bugs.ruby-lang.org/issues/14944
Benchmark is here.
Testing
Existing tests covers this change.