Skip to content

MONGOID-4889 Optimize batch assignment of embedded documents #6008

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

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 ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants