aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods.rb
diff options
context:
space:
mode:
authorGodfrey Chan <godfreykfc@gmail.com>2014-05-22 11:58:20 -0700
committerGodfrey Chan <godfreykfc@gmail.com>2014-05-22 14:35:15 -0700
commit28d52c59f2cb32180ca24770bf95597ea3ad8198 (patch)
treedf363f449a9ce95dc018712d43929d80c9fca202 /activerecord/lib/active_record/attribute_methods.rb
parent2d73f5ae2fe75427d56853f107abda21754f1b1a (diff)
downloadrails-28d52c59f2cb32180ca24770bf95597ea3ad8198.tar.gz
rails-28d52c59f2cb32180ca24770bf95597ea3ad8198.tar.bz2
rails-28d52c59f2cb32180ca24770bf95597ea3ad8198.zip
Avoid slowing down AR object initialization
2d73f5a forces AR to enter the `define_attribute_methods` method whenever it instantiate a record from the `init_with` entry point. This is a potential performance hotspot, because `init_with` is called from all `find*` family methods, and `define_attribute_methods` is slow because it tries to acquire a lock on the mutex everytime it is entered. By using [DCL](http://en.wikipedia.org/wiki/Double-checked_locking), we can avoid grabbing the lock most of the time when the attribute methods are already defined (the common case). This is made possible by the fact that reading an instance variable is an atomic operation in Ruby. Credit goes to Aaron Patterson for pointing me to DCL and filling me in on the atomicity guarantees in Ruby. [*Godfrey Chan*, *Aaron Patterson*]
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods.rb')
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb1
1 files changed, 1 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 6c2403d87e..b9141b9b33 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -66,6 +66,7 @@ module ActiveRecord
# Generates all the attribute related methods for columns in the database
# accessors, mutators and query methods.
def define_attribute_methods # :nodoc:
+ return false if @attribute_methods_generated
# Use a mutex; we don't want two thread simultaneously trying to define
# attribute methods.
generated_attribute_methods.synchronize do