aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/scoping
diff options
context:
space:
mode:
authorGuo Xiang Tan <tgx_world@hotmail.com>2015-09-07 15:13:00 +0800
committerGuo Xiang Tan <tgx_world@hotmail.com>2015-09-07 15:13:00 +0800
commit69de09c5cee19d63400c4b62d2ebeac5a89eb14d (patch)
tree6e76fbd28a12e8b46f82e4d881e2d5a520e60108 /activerecord/lib/active_record/scoping
parentf1f0a3f8d99aef8aacfa81ceac3880dcac03ca06 (diff)
downloadrails-69de09c5cee19d63400c4b62d2ebeac5a89eb14d.tar.gz
rails-69de09c5cee19d63400c4b62d2ebeac5a89eb14d.tar.bz2
rails-69de09c5cee19d63400c4b62d2ebeac5a89eb14d.zip
PERF: Don't create a Relation when it is not needed.
Benchmark script used: ``` begin require 'bundler/inline' rescue LoadError => e $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler' raise e end gemfile(true) do source 'https://rubygems.org' gem 'rails', path: '~/rails' # master against ref "f1f0a3f8d99aef8aacfa81ceac3880dcac03ca06" gem 'arel', github: 'rails/arel', branch: 'master' gem 'rack', github: 'rack/rack', branch: 'master' gem 'sass' gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master' gem 'sprockets', github: 'rails/sprockets', branch: 'master' gem 'pg' gem 'benchmark-ips' end require 'active_record' require 'benchmark/ips' ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench') ActiveRecord::Migration.verbose = false ActiveRecord::Schema.define do create_table :users, force: true do |t| t.string :name, :email t.timestamps null: false end end class User < ActiveRecord::Base; end attributes = { name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", email: "foobar@email.com", } 1000.times { User.create!(attributes) } Benchmark.ips(5, 3) do |x| x.report('all') { User.all } end key = if RUBY_VERSION < '2.2' :total_allocated_object else :total_allocated_objects end before = GC.stat[key] User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") after = GC.stat[key] puts "Total Allocated Object: #{after - before}" ``` Before: ``` Calculating ------------------------------------- all 17.569k i/100ms ------------------------------------------------- all 190.854k (± 3.3%) i/s - 966.295k Total Allocated Object: 85 ``` After: ``` Calculating ------------------------------------- all 22.237k i/100ms ------------------------------------------------- all 262.715k (± 5.5%) i/s - 1.312M Total Allocated Object: 80 ```
Diffstat (limited to 'activerecord/lib/active_record/scoping')
-rw-r--r--activerecord/lib/active_record/scoping/default.rb3
1 files changed, 2 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/scoping/default.rb b/activerecord/lib/active_record/scoping/default.rb
index a1adf8e3ee..6454f17fdb 100644
--- a/activerecord/lib/active_record/scoping/default.rb
+++ b/activerecord/lib/active_record/scoping/default.rb
@@ -99,12 +99,13 @@ module ActiveRecord
self.default_scopes += [scope]
end
- def build_default_scope(base_rel = relation) # :nodoc:
+ def build_default_scope(base_rel = nil) # :nodoc:
return if abstract_class?
if !Base.is_a?(method(:default_scope).owner)
# The user has defined their own default scope method, so call that
evaluate_default_scope { default_scope }
elsif default_scopes.any?
+ base_rel ||= relation
evaluate_default_scope do
default_scopes.inject(base_rel) do |default_scope, scope|
default_scope.merge(base_rel.scoping { scope.call })