Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance degradation on all ActiveRecord instances when enable_parent_assignment = true #183

Closed
ermolaev opened this issue Sep 12, 2024 · 1 comment

Comments

@ermolaev
Copy link

ermolaev commented Sep 12, 2024

Hi, I noticed that after adding the gem, accessing model attributes works slower.
The problem is with setting StoreModel.config.enable_parent_assignment = true, perhaps it's better to set it to false by default.

gem "store_model", require: false

rails runner -e production getters_bench.rb 3.7x slowly

require "benchmark/ips"

ActiveRecord::Schema.define do
  create_table :models, force: true do |t|
    t.string :name
    t.integer :ids, array: true
    t.timestamps
  end
end

class Model < ActiveRecord::Base; end

m = Model.create(name: "name", ids: [1, 2, 3, 4, 5])
Benchmark.ips do |x|
  x.report("without store_model") { m.id; m.created_at; m.ids  }
end

require "store_model"
module StoreModel # :nodoc:
  class Railtie < Rails::Railtie # :nodoc:
    ActiveSupport.on_load(:active_record) do
      if StoreModel.config.enable_parent_assignment
        ActiveModel::Attributes.prepend(Attributes)
        prepend(Base)
      end
    end
  end
end

Benchmark.ips do |x|
  x.report("with store_model") { m.id; m.created_at; m.ids }
end

# Warming up --------------------------------------
#  without store_model   193.067k i/100ms
# Calculating -------------------------------------
#  without store_model      1.901M (± 1.3%) i/s -      9.653M in   5.079277s

# Warming up --------------------------------------
#     with store_model    50.543k i/100ms
# Calculating -------------------------------------
#     with store_model    509.177k (± 1.4%) i/s -      2.578M in   5.063416s

rails runner -e production setters_bench.rb 2.6x slowly

class Model < ActiveRecord::Base; end

m = Model.create(name: "name", ids: [1, 2, 3, 4, 5])
new_arr = [1, 2, 3]

Benchmark.ips do |x|
  x.report("without store_model") { m.ids = new_arr }
end

require "store_model"
module StoreModel # :nodoc:
  class Railtie < Rails::Railtie # :nodoc:
    ActiveSupport.on_load(:active_record) do
      if StoreModel.config.enable_parent_assignment
        ActiveModel::Attributes.prepend(Attributes)
        prepend(Base)
      end
    end
  end
end

Benchmark.ips do |x|
  x.report("with store_model") { m.ids = new_arr }
end

# Warming up --------------------------------------
#  without store_model   229.502k i/100ms
# Calculating -------------------------------------
#  without store_model      2.298M (± 2.4%) i/s -     11.705M in   5.095917s
#
# Warming up --------------------------------------
#     with store_model    86.820k i/100ms
# Calculating -------------------------------------
#     with store_model    872.129k (± 1.6%) i/s -      4.428M in   5.078182s
@DmitryTsepelev
Copy link
Owner

Hey! Good call, I'll change it in the next major release. Separate thanks for the bench 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants