dm-timestamps causes major (100x in this example) slowdowns when creating multiple children at once
Reported by Greg Campbell | December 16th, 2009 @ 12:08 PM
In the script at http://gist.github.com/258013, requiring dm-timestamps reproducibly causes the operation to run over 100 times times slower, even if there are no timestamp properties used. Furthermore, adding timestamp properties worsens the problem, as the parent and grandparent node will be re-saved for every child saved in the list. I believe the problem to be the following:
- for each child node saved, save_parents is called
- this triggers dm-timestamps' set_timestamps_on_save method
- set_timestamps_on_save returns unless dirty? is true. dirty? recursively calls dirty_parents? and dirty_children?, and will be true until all children have been saved, as I understand it
One solution would be to check dirty_self? rather than dirty?, but that's api private at this point.
Comments and changes to this ticket
- Tag changed from dm-timestamps, performance to dm-timestamps, performance, regression
Tagging this as a regression. Although it doesn't technically break functionality, it can make certain previously-supported operations unusably slow. dkubb, please remove the tag if you find it inappropriate, of course.
The reason this is happening is that when saving an object graph due to circular dependencies, the object's save method may be called more than once.
I've fixed this problem by adding a guard clause to Resource#save_self that returns if the object isn't dirty. This also allows me to remove up some logic from create and update that was short circuiting if the object wasn't dirty.
Will push a commit once I've verified the specs pass with every adapter.
- State changed from accepted to resolved
(from [1b7669379b79e7e85be9d6d523f2777b5da0c803]) Skip saving if the dirty test returns false
- This will speed up any cases where the resource is being saved and there are before(:save) or after(:save) filters.
- Removed now redundant code from create and update