Skip to content

MONGOID-4889 Optimize batch assignment of embedded documents#6008

Merged
jamis merged 4 commits intomongodb:masterfrom
jamis:4889-optimize-batch-assignment
Jul 18, 2025
Merged

MONGOID-4889 Optimize batch assignment of embedded documents#6008
jamis merged 4 commits intomongodb:masterfrom
jamis:4889-optimize-batch-assignment

Conversation

@jamis
Copy link
Contributor

@jamis jamis commented Jul 2, 2025

When associating multiple embedded documents in a single assignment, the existing code was inefficiently looping over all records repeatedly, resulting in a significant performance impact. This PR attempts to minimize the number of loops needed to accomplish the same thing, while keeping the ordering of callbacks the same and otherwise attempting to not break backward compatibility.

To test the performance of this PR, the following benchmark (from MONGOID-4889) was used:

class Foo
  include Mongoid::Document
  embeds_many :bars
end

class Bar
  include Mongoid::Document
  embedded_in :foo
end

require 'benchmark'
array_1k = Array.new(1000) { Bar.new }
array_2k = Array.new(2000) { Bar.new }
array_3k = Array.new(3000) { Bar.new }
array_4k = Array.new(4000) { Bar.new }
array_5k = Array.new(5000) { Bar.new }

Benchmark.bm do |x|
  x.report('1k') { Foo.new.bars = array_1k }
  x.report('2k') { Foo.new.bars = array_2k }
  x.report('3k') { Foo.new.bars = array_3k }
  x.report('4k') { Foo.new.bars = array_4k }
  x.report('5k') { Foo.new.bars = array_5k }
end

With the previous implementation, the timings were abyssmal:

        user     system      total        real
1k  0.721604   0.002515   0.724119 (  0.724148)
2k  2.834939   0.008708   2.843647 (  2.843895)
3k  6.383648   0.017409   6.401057 (  6.401207)
4k 11.313247   0.035579  11.348826 ( 11.349941)
5k 17.895191   0.096859  17.992050 ( 18.048693)

Things look much better with the optimized implementation:

        user     system      total        real
1k  0.031262   0.000538   0.031800 (  0.031798)
2k  0.041094   0.000543   0.041637 (  0.041638)
3k  0.058909   0.000606   0.059515 (  0.059517)
4k  0.090872   0.000752   0.091624 (  0.091641)
5k  0.096289   0.001358   0.097647 (  0.097666)

@jamis jamis requested a review from a team as a code owner July 2, 2025 22:41
@jamis jamis requested a review from comandeo-mongo July 2, 2025 22:41
@johnnyshields
Copy link
Contributor

Awesome, great work ❤️

@jamis jamis merged commit 7e9d95a into mongodb:master Jul 18, 2025
62 checks passed
@jamis jamis deleted the 4889-optimize-batch-assignment branch July 18, 2025 15:59
jamis added a commit to jamis/mongoid that referenced this pull request Jul 18, 2025
…#6008)

* MONGOID-4889 Optimize batch assignment of embedded documents

* rubocop appeasement

* simplify some refactoring artifacts

* improve the name of the extracted method
jamis added a commit to jamis/mongoid that referenced this pull request Jul 18, 2025
…#6008)

* MONGOID-4889 Optimize batch assignment of embedded documents

* rubocop appeasement

* simplify some refactoring artifacts

* improve the name of the extracted method
jamis added a commit that referenced this pull request Aug 19, 2025
…6010)

* MONGOID-4889 Optimize batch assignment of embedded documents

* rubocop appeasement

* simplify some refactoring artifacts

* improve the name of the extracted method
jamis added a commit that referenced this pull request Aug 19, 2025
…6011)

* MONGOID-4889 Optimize batch assignment of embedded documents

* rubocop appeasement

* simplify some refactoring artifacts

* improve the name of the extracted method
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

Successfully merging this pull request may close these issues.

3 participants