Skip to content

Commit

Permalink
Don't run callbacks on batch 1-n and n-n operations
Browse files Browse the repository at this point in the history
- [close #2146]
  • Loading branch information
durran committed Jun 27, 2012
1 parent 00206b6 commit 2b04320
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 40 deletions.
5 changes: 1 addition & 4 deletions lib/mongoid/relations/embedded/batchable.rb
Expand Up @@ -262,9 +262,7 @@ def pre_process_batch_insert(docs)
append(doc)
if persistable? && !_assigning?
self.path = doc.atomic_path unless path
if doc.valid?(:create)
doc.run_before_callbacks(:save, :create)
else
if doc.invalid?(:create)
self.inserts_valid = false
end
end
Expand Down Expand Up @@ -314,7 +312,6 @@ def pre_process_batch_remove(docs, method)
def post_process_batch_insert(docs)
docs.each do |doc|
doc.new_record = false
doc.run_after_callbacks(:create, :save)
doc.post_persist
end
end
Expand Down
24 changes: 12 additions & 12 deletions lib/mongoid/relations/referenced/many.rb
Expand Up @@ -50,13 +50,13 @@ def <<(*args)
#
# @since 2.4.0
def concat(documents)
inserts = []
docs, inserts = [], []
documents.each do |doc|
next unless doc
append(doc)
save_or_delay(doc, inserts) if persistable?
save_or_delay(doc, docs, inserts) if persistable?
end
persist_delayed(inserts)
persist_delayed(docs, inserts)
self
end

Expand Down Expand Up @@ -387,15 +387,15 @@ def method_missing(name, *args, &block)
# @example Persist the delayed batch inserts.
# relation.persist_delayed([ doc ])
#
# @param [ Array<Document> ] inserts The delayed inserts.
# @param [ Array<Document> ] docs The delayed inserts.
# @param [ Array<Hash> ] inserts The raw insert document.
#
# @since 3.0.0
def persist_delayed(inserts)
if inserts.any?
collection.insert(inserts.map(&:as_document))
inserts.each do |doc|
def persist_delayed(docs, inserts)
if docs.any?
collection.insert(inserts)
docs.each do |doc|
doc.new_record = false
doc.run_after_callbacks(:create, :save)
doc.post_persist
end
end
Expand Down Expand Up @@ -478,10 +478,10 @@ def remove_not_in(ids)
# @param [ Array<Document> ] inserts The inserts.
#
# @since 3.0.0
def save_or_delay(doc, inserts)
def save_or_delay(doc, docs, inserts)
if doc.new_record? && doc.valid?(:create)
inserts.push(doc)
doc.run_before_callbacks(:save, :create)
docs.push(doc)
inserts.push(doc.as_document)
else
doc.save
end
Expand Down
6 changes: 3 additions & 3 deletions lib/mongoid/relations/referenced/many_to_many.rb
Expand Up @@ -52,21 +52,21 @@ def <<(*args)
#
# @since 2.4.0
def concat(documents)
ids, inserts = [], []
ids, docs, inserts = [], [], []
documents.each do |doc|
next if doc.nil? || target.include?(doc)
append(doc)
if persistable? || _creating?
ids.push(doc.id)
save_or_delay(doc, inserts)
save_or_delay(doc, docs, inserts)
else
base.send(foreign_key).push(doc.id) and unsynced(base, foreign_key)
end
end
if persistable? || _creating?
base.push_all(foreign_key, ids)
end
persist_delayed(inserts)
persist_delayed(docs, inserts)
self
end

Expand Down
74 changes: 53 additions & 21 deletions perf/benchmark.rb
Expand Up @@ -55,9 +55,9 @@

Person.delete_all
end
end

GC.start
GC.start
end

person = Person.create(:birth_date => Date.new(1970, 1, 1))

Expand Down Expand Up @@ -104,17 +104,31 @@
person.addresses.clear
GC.start

bm.report("#push ") do
i.times do |n|
person.addresses.push(
Address.new(
:street => "Wienerstr. #{n}",
:city => "Berlin",
:post_code => "10999"
)
)
end
end

person.addresses.clear
GC.start

bm.report("#push (batch) ") do
[].tap do |addresses|
i.times do |n|
addresses << Address.new(
:street => "Wienerstr. #{n}",
:city => "Berlin",
:post_code => "10999"
)
end
person.addresses.push(addresses)
addresses = []
i.times do |n|
addresses << Address.new(
:street => "Wienerstr. #{n}",
:city => "Berlin",
:post_code => "10999"
)
end
person.addresses.concat(addresses)
end

bm.report("#each ") do
Expand Down Expand Up @@ -181,6 +195,8 @@
end
end

GC.start

bm.report("#count ") do
person.posts.count
end
Expand All @@ -192,13 +208,21 @@
Post.delete_all
GC.start

bm.report("#push ") do
i.times do |n|
person.posts.push(Post.new(:title => "Posting #{n}"))
end
end

Post.delete_all
GC.start

bm.report("#push (batch) ") do
[].tap do |posts|
i.times do |n|
posts << Post.new(:title => "Posting #{n}")
end
person.posts.push(posts)
posts = []
i.times do |n|
posts << Post.new(:title => "Posting #{n}")
end
person.posts.concat(posts)
end

bm.report("#each ") do
Expand Down Expand Up @@ -274,13 +298,21 @@
Preference.delete_all
GC.start

bm.report("#push ") do
i.times do |n|
person.preferences.push(Preference.new(:name => "Preference #{n}"))
end
end

Preference.delete_all
GC.start

bm.report("#push (batch) ") do
[].tap do |preferences|
i.times do |n|
preferences << Preference.new(:name => "Preference #{n}")
end
person.preferences.push(preferences)
preferences = []
i.times do |n|
preferences << Preference.new(:name => "Preference #{n}")
end
person.preferences.concat(preferences)
end

bm.report("#each ") do
Expand Down

0 comments on commit 2b04320

Please sign in to comment.