Skip to content
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

Improve performance when resurrecting an object with many backlinks #7218

Merged
merged 2 commits into from
Dec 21, 2023

Conversation

jedelbo
Copy link
Contributor

@jedelbo jedelbo commented Dec 20, 2023

The process of first removing the backlink from the tombstone and then creating it again in the live object took a long time. As the backlinks will end up being identical, we can just move the whole structure from the tombstone to the new object and then just replace the link in the linking object without worring about backlinks.

This change is only done for link and linklist properties.

Fixes #7217

What, How & Why?

☑️ ToDos

  • 📝 Changelog update
  • 🚦 Tests (or not relevant)
  • C-API, if public C++ API changed
  • bindgen/spec.yml, if public C++ API changed

The process of first removing the backlink from the tombstone and then
creating it again in the live object took a long time. As the backlinks
will end up being identical, we can just move the whole structure from
the tombstone to the new object and then just replace the link in
the linking object without worring about backlinks.

This change is only done for link and linklist properties.
@jedelbo jedelbo marked this pull request as ready for review December 20, 2023 11:42
@jedelbo jedelbo changed the title Improve performance when ressurecting and object with many backlinks Improve performance when ressurecting an object with many backlinks Dec 20, 2023
Copy link
Contributor

@finnschiermer finnschiermer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very smart.

Copy link

coveralls-official bot commented Dec 20, 2023

Pull Request Test Coverage Report for Build jorgen.edelbo_12

  • 106 of 106 (100.0%) changed or added relevant lines in 5 files are covered.
  • 87 unchanged lines in 16 files lost coverage.
  • Overall coverage increased (+0.03%) to 91.741%

Files with Coverage Reduction New Missed Lines %
src/realm/index_string.cpp 1 87.81%
src/realm/array_string.cpp 2 88.0%
src/realm/obj.cpp 2 91.75%
src/realm/query_expression.cpp 2 87.18%
src/realm/sync/network/websocket.cpp 2 74.23%
test/test_lang_bind_helper.cpp 2 93.3%
src/realm/sync/client.cpp 3 91.28%
test/test_util_network.cpp 3 97.2%
src/realm/link_translator.cpp 4 80.33%
src/realm/sync/noinst/protocol_codec.hpp 4 76.55%
Totals Coverage Status
Change from base Build 1928: 0.03%
Covered Lines: 232602
Relevant Lines: 253541

💛 - Coveralls

@jedelbo jedelbo changed the title Improve performance when ressurecting an object with many backlinks Improve performance when resurrecting an object with many backlinks Dec 20, 2023
CHANGELOG.md Outdated Show resolved Hide resolved
auto t = m_table->get_opposite_table(col);
auto c = m_table->get_opposite_column(col);
auto backlinks = other.get_all_backlinks(col);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clever idea. It leaks the implementation of backlinks storage a bit here, but we have accepted worse in the name of performance.

@@ -614,7 +612,7 @@ void SyncReplication::set_clear(const CollectionBase& set)
void SyncReplication::dictionary_update(const CollectionBase& dict, const Mixed& key, const Mixed& value)
{
// If link is unresolved, it should not be communicated.
if (value.is_type(type_Link, type_TypedLink) && value.get<ObjKey>().is_unresolved()) {
if (value.is_unresolved_link()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -794,4 +806,69 @@ TEST(Links_ManyObjects)
tr->commit();
}

TEST(Unresolved_PerformanceLinks)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be ideal to have a micro benchmark for this so we can track it long term to detect regressions, but that's not blocking for me.

Co-authored-by: James Stone <[email protected]>
@jedelbo jedelbo merged commit e1fcdae into master Dec 21, 2023
34 of 35 checks passed
@jedelbo jedelbo deleted the je/RCORE-1919 branch December 21, 2023 14:43
@bdkjones
Copy link

bdkjones commented Jan 4, 2024

Is there any reason this change might have introduced a performance regression for very large initial sync jobs?

Note that the changesets go from taking ~430ms to ~3000ms after a number of them have been processed. If I terminate my app (built with the Realm Swift SDK) and run it again, the changesets again process in about 430ms.

Screenshot 2024-01-04 at 13 15 20

The only change made to the app was updating Realm from 10.44.x to 10.45.2. I did not observe this slowdown during initial bootstrapping on 10.44.x.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 21, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Resurrecting an object with many backlinks takes too long
4 participants