You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We're trying to make instantiating models cheaper (for example doing
`Post.new`), and discovered in the course of profiling that
`respond_to?` is responsible for some amount of initialization
allocations.
This patch changes `Model.respond_to?` to not allocate anymore which
should help initialization performance (as well as other queries).
Here is the benchmark we used:
```ruby
require "active_record"
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Schema.define do
create_table :posts, force: true do |t|
t.string :title, default: "hello"
t.text :body, default: "i am a blog post"
t.string :author, default: "aaron"
t.boolean :published, default: true
t.integer :likes, default: 1000000
end
end
class Post < ActiveRecord::Base
end
5.times { Post.new }
def m
x = GC.stat(:total_allocated_objects)
yield
GC.stat(:total_allocated_objects) - x
end
allocs = m { 5000.times { Post.new } }
p ALLOCATIONS_PER_MODEL: (allocs / 5000)
allocs = m { 5000.times { Post.respond_to?(:default_scope) } }
p ALLOCATIONS_PER_RESPOND_TO: (allocs / 5000)
```
Before this patch:
```
$ bundle exec ruby -Iactiverecord/lib:~/git/vernier/lib test.rb
-- create_table(:posts, {force: true})
-> 0.0045s
{ALLOCATIONS_PER_MODEL: 9}
{ALLOCATIONS_PER_RESPOND_TO: 2}
```
After this patch:
```
$ bundle exec ruby -Iactiverecord/lib:~/git/vernier/lib test.rb
-- create_table(:posts, {force: true})
-> 0.0045s
{ALLOCATIONS_PER_MODEL: 7}
{ALLOCATIONS_PER_RESPOND_TO: 0}
```
Co-Authored-By: Eileen M. Uchitelle <[email protected]>
0 commit comments