2016-08-01 3 views
0

Mit Realm 1.0.2 unter OS X habe ich eine Realm-Datei, die ~ 3,5 GB erreicht. Jetzt dauert das Schreiben einer Menge neuer Objekte im Durchschnitt etwa 30s - 1min, was die Sache ziemlich langsam macht. Nach dem Profiling sieht es eindeutig wie commitWriteTransaction dauert einen großen Teil der Zeit.Leistung von commitWriteTransaction für eine große Realm-Datei

Ist die Leistung in diesem Fall normal/erwartet? Und wenn ja, welche Strategien wären verfügbar, um diese Zeit zu sparen?

+0

Hallo Kettch. Speichern Sie tatsächlich ~ 3,5 Gb Daten in Ihrem Realm, oder ist die Realm-Datei wesentlich größer als die Menge an Daten, die Sie tatsächlich speichern? – AustinZ

+0

Sie verwenden definitiv nicht 'autoreleasepool' um Ihre Hintergrund-Thread-Realm-Instanzen. Und natürlich sollten Sie, siehe [Beispiel] (http://stackoverflow.com/a/34087874/2413303) – EpicPandaForce

+0

Ja, da sind tatsächlich 3,5 GB Daten drin. Abgesehen von Objekten, die weniger zahlreich sind, sind das ungefähr 60 Millionen Objekte mit jeweils ein paar Doppeln (jetzt, da ich darüber nachdenke, könnte ich wahrscheinlich mit Schwimmern davonkommen. Ich muss das versuchen). Wie für den Autorelease-Pool werden die Schreibschübe tatsächlich in einer Methode ausgeführt, die jedes Mal vom Rückruf einer NSURLConnection aufgerufen wird, so dass der Autorelease-Pool zwischen jedem Commit Zeit haben würde. – Kettch

Antwort

0

Realm verwendet copy-on-write Semantik, wenn Änderungen in Schreibtransaktionen durchgeführt werden.

Je größer die Struktur ist, die gegabelten & kopiert werden muss, desto länger dauert es, den Vorgang durchzuführen.

Dieses kleine unwissenschaftlich Benchmark auf meinem 2,8 GHz i7 MacBook Pro

import Foundation 
import RealmSwift 

class Model: Object { 
    dynamic var prop1 = 0.0 
    dynamic var prop2 = 0.0 
} 

// Add 60 million objects with two Double properties in batches of 10 million 
autoreleasepool { 
    for _ in 0..<6 { 
    let start = NSDate() 
    let realm = try! Realm() 
    try! realm.write { 
     for _ in 0..<10_000_000 { 
     realm.add(Model()) 
     } 
    } 
    print(realm.objects(Model.self).count) 
    print("took \(-start.timeIntervalSinceNow)s") 
    } 
} 

// Add one item to that Realm 
autoreleasepool { 
    let start = NSDate() 
    let realm = try! Realm() 
    try! realm.write { 
    realm.add(Model()) 
    } 
    print(realm.objects(Model.self).count) 
    print("took \(-start.timeIntervalSinceNow)s") 
} 

protokolliert die folgenden:

10000000 
took 25.6072470545769s 
20000000 
took 23.7239990234375s 
30000000 
took 24.4556020498276s 
40000000 
took 23.9790390133858s 
50000000 
took 24.5923230051994s 
60000000 
took 24.2157150506973s 
60000001 
took 0.0106720328330994s 

So können Sie, dass das Hinzufügen viele Objekte auf dem Realm sehen, ohne Beziehungen ist ziemlich schnell und bleibt linear proportional zur Anzahl der hinzuzufügenden Objekte.

Es ist also wahrscheinlich, dass Sie mehr tun, als nur Objekte zum Realm hinzuzufügen, vielleicht aktualisieren Sie vorhandene Objekte, wodurch sie kopiert werden?

Wenn Sie einen Wert von allen Objekten als Teil Ihrer Schreibtransaktionen lesen, wächst dieser proportional zur Anzahl der Objekte.

Das Vermeiden dieser Dinge wird Ihre Schreibtransaktionen verkürzen.

+0

Ich mache keine Abfrage dort, und keine Aktualisierung auf einem vorhandenen Objekt . Aber die Objekte, die ich einfüge, enthalten ein bisschen mehr als nur ein bisschen Doppel: sie haben auch ein indiziertes NSDate und eine Beziehung zu einer anderen Art von Objekt (andersherum ist ein readonly RLMLinkingObjects). Könnte das sein, was diese Wachstumszeiten verursacht? – Kettch

+0

Eine indizierte Eigenschaft allein wird die Dinge immer noch linear halten. Die Beziehung ist wahrscheinlich der teure Teil in Ihrem Fall zu verzweigen. Ich denke, ich müsste etwas Code sehen, um dir weiter zu helfen. – jpsim

Verwandte Themen