Comments (9)
➤ PM Bot commented:
Jira ticket: RNET-1131
from realm-dotnet.
My guess is that just parsing the query is taking the majority of the time here. I don't expect this is a case we'd like to actively optimize for, but if you're curious, you could try and measure how long var toDelete = realm.All<MyObject>().Filter(sb.ToString());
takes vs realm.RemoveRange
.
from realm-dotnet.
My guess is that just parsing the query is taking the majority of the time here. I don't expect this is a case we'd like to actively optimize for, but if you're curious, you could try and measure how long
var toDelete = realm.All<MyObject>().Filter(sb.ToString());
takes vsrealm.RemoveRange
.
Thank you for a quick answer and sorry for the bad formatting in OP.
It does seem it actual is realm.RemoveRange that is slow: I should have tested the filtering before saying that. The filtering looks pretty good.
var removeRangeSw = new Stopwatch();
var filterSw = new Stopwatch();
filterSw.Start();
var firstId = ids[0].ToString();`
var sbb = new StringBuilder();
sbb.Append($"Id == uuid({firstId})");
for (int i = 1; i < ids.Length; i++)
{
sbb.Append(" OR ");
sbb.Append("Id == uuid(");
sbb.Append(ids[i]);
sbb.Append(")");
}
realm.Write(() =>
{
var toDelete = realm.All<MyObject>().Filter(sbb.ToString());
filterSw.Stop();
removeRangeSw.Start();
realm.RemoveRange(toDelete);
removeRangeSw.Stop();
});
Console.WriteLine($"Elapsed time filtering: {filterSw.ElapsedMilliseconds} ms");
Console.WriteLine($"Elapsed time remove range: {removeRangeSw.ElapsedMilliseconds} ms");
Console.WriteLine($"Total deletion time {filterSw.ElapsedMilliseconds + removeRangeSw.ElapsedMilliseconds} ms");
//Output:
//Elapsed time filtering: 451 ms
//Elapsed time remove range: 17655 ms
//Total deletion time 18106 ms
from realm-dotnet.
just a little correction. I have previosly tested on a more advanced class. I now tested on the class that I wrote here and I get total deletion time of around 10000ms
from realm-dotnet.
I was able to somewhat reproduce this with the following code:
using System.Diagnostics;
using Realms;
using var realm = Realm.GetInstance("RemoveRange.realm");
var ids = Enumerable.Range(0, 100_000).Select(_ => Guid.NewGuid()).ToArray();
realm.Write(() =>
{
foreach (var id in ids)
{
realm.Add(new PrimaryKeyGuidObject
{
Id = id
});
}
});
var sw = new Stopwatch();
sw.Start();
var query = string.Join(" OR ", ids.Select(i => $"Id == uuid({i})"));
Console.WriteLine($"Construct string query: {sw.ElapsedMilliseconds}");
var results = realm.All<PrimaryKeyGuidObject>().Filter(query);
Console.WriteLine($"Construct Realm query: {sw.ElapsedMilliseconds}");
realm.Write(() =>
{
realm.RemoveRange(results);
Console.WriteLine($"RemoveRange: {sw.ElapsedMilliseconds}");
});
Console.WriteLine($"Commit: {sw.ElapsedMilliseconds}");
public partial class PrimaryKeyGuidObject : IRealmObject
{
[PrimaryKey]
public Guid Id { get; set; }
}
On my M1 mac, this prints out:
Construct string query: 25
Construct Realm query: 288
RemoveRange: 7726
Commit: 7742
I.e. the removal takes about 7.5 seconds. It's not amazing, but it's not the end of the world either, so I don't expect we'll go out of our way to optimize this use case. I'll reach out to the core database team and see if they spot any low-hanging fruit that could speed it up.
from realm-dotnet.
Another interesting observation - if instead of constructing a massive query and deleting all objects that match it, you delete the objects 1 by 1, this is much faster. Essentially, by replacing the second .Write
with:
foreach (var id in ids)
{
realm.Remove(realm.Find<PrimaryKeyGuidObject>(id)!);
}
I get the whole operation to complete in 350 ms.
from realm-dotnet.
I was able to somewhat reproduce this with the following code:
using System.Diagnostics; using Realms; using var realm = Realm.GetInstance("RemoveRange.realm"); var ids = Enumerable.Range(0, 100_000).Select(_ => Guid.NewGuid()).ToArray(); realm.Write(() => { foreach (var id in ids) { realm.Add(new PrimaryKeyGuidObject { Id = id }); } }); var sw = new Stopwatch(); sw.Start(); var query = string.Join(" OR ", ids.Select(i => $"Id == uuid({i})")); Console.WriteLine($"Construct string query: {sw.ElapsedMilliseconds}"); var results = realm.All<PrimaryKeyGuidObject>().Filter(query); Console.WriteLine($"Construct Realm query: {sw.ElapsedMilliseconds}"); realm.Write(() => { realm.RemoveRange(results); Console.WriteLine($"RemoveRange: {sw.ElapsedMilliseconds}"); }); Console.WriteLine($"Commit: {sw.ElapsedMilliseconds}"); public partial class PrimaryKeyGuidObject : IRealmObject { [PrimaryKey] public Guid Id { get; set; } }On my M1 mac, this prints out:
Construct string query: 25 Construct Realm query: 288 RemoveRange: 7726 Commit: 7742
I.e. the removal takes about 7.5 seconds. It's not amazing, but it's not the end of the world either, so I don't expect we'll go out of our way to optimize this use case. I'll reach out to the core database team and see if they spot any low-hanging fruit that could speed it up.
thank you for reply
I just tried this class ("PrimaryKeyGuidObject/MyObject") with sqlite (Microsoft.Data.Sqlite). I takes 682ms. So Realm is about 11x times slower in delete range.
It is weird that inserts are must faster than deletes?
from realm-dotnet.
I agree - this appears to be hitting some weirdness with how the query is evaluated and maintained throughout the deletion. Not sure if you saw my follow-up comment, but looking up objects and deleting them one by one seems to be, unintuitively, much faster than passing down a query.
from realm-dotnet.
Another interesting observation - if instead of constructing a massive query and deleting all objects that match it, you delete the objects 1 by 1, this is much faster. Essentially, by replacing the second
.Write
with:foreach (var id in ids) { realm.Remove(realm.Find<PrimaryKeyGuidObject>(id)!); }I get the whole operation to complete in 350 ms.
I agree - this appears to be hitting some weirdness with how the query is evaluated and maintained throughout the deletion. Not sure if you saw my follow-up comment, but looking up objects and deleting them one by one seems to be, unintuitively, much faster than passing down a query.
very nice, I can confirm this. Now we are seeing more reasonable ms, and even faster than sqlite which is resonating with other comparisons I have tried.
Thank you for this tip! very useful.
however i didnt expect RemoveRange to be so slow. maybe there is some weirdness going on there
from realm-dotnet.
Related Issues (20)
- Handle Role Changes without Client Reset HOT 1
- Crash: Realm.SyncSession is only valid for synchronized Realms HOT 6
- Realm.DeleteRealm() creates lock file if Realm doesn't exist HOT 2
- Change passing of tests on CI HOT 3
- Add tests for sync schema migration HOT 1
- Fix equality comparison for collections in mixed HOT 1
- Realm Obfuscation (Unity + Local Database) HOT 16
- Add tests for notifications with collections in mixed HOT 1
- Fix `SyncMigrationTests.Migration_FailsWithFutureVersion` HOT 1
- Follow up on progress notification HOT 1
- App.CurrentUser doesn't become `null` after anonymous user logout HOT 2
- Compacting a Realm results in an upgrade prompt in Realm Studio HOT 2
- Encrypted Realm created on Android won't open on Windows HOT 5
- Trying to open a particular Realm DB file throws the following exception - "Upgrading from file format version 22 to 24 D:\a\realm-dotnet\realm-dotnet\wrappers\realm-core\src\realm/util/encrypted_file_mapping.hpp:180: [realm-core-14.5.1] Assertion failed: local_ndx < m_page_state.size() with (local_ndx, m_page_state.size(), size_t(addr), size_t(m_addr), m_page_shift) = [85, 1, 2331762327552, 2331762294784, 16] <backtrace not supported on this platform>" HOT 9
- SDKs should not consume stitch_ prefixed fields HOT 1
- Error when trying to migrate IList data type with DynamicApi.GetList HOT 6
- IRealmCollection SubscribeForNotifications not working!!! HOT 6
- Add support for Migration.FindInNewRealm HOT 1
- RealmResults (from Realm live queries) no longer notify UI observers HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from realm-dotnet.