2012-05-01 3 views
7

Ich analysiere eine Tonne Daten, die ich anfänglich in einen Core-Datenspeicher einfüge.Verbessern Sie die Geschwindigkeit beim Aktualisieren vorhandener Datensätze (~ 11.000) in den Core-Daten

Zu einem späteren Zeitpunkt, Parsing ich die gleiche XML, obwohl einige Mai wurden aktualisiert. Was ich dann tue, ist, nach einem existierenden Datensatz mit dem gleichen Tag zu suchen, und wenn es einen bereits gibt, aktualisiere ich den Datensatz mit den Daten.

Während meine erste Analyse (etwa 11.000 Datensätze) dauert etwa 8 Sekunden, scheint die Aktualisierung teuer und dauert 144 Sekunden (das sind Simulator läuft, also deutlich länger auf tatsächlichen Geräten).

Während das erste Mal in Ordnung ist (ich zeige einen Fortschrittsbalken), ist der zweite unannehmbar lang, und ich möchte etwas tun, um die Geschwindigkeit zu verbessern (obwohl es im Hintergrund in einem separaten Thread passiert) .

Leider ist es keine Frage von find-or-create, da die Daten in der XML für einzelne Datensätze geändert haben können, so dass jeder im Wesentlichen ein Update benötigt.

Ich habe die Attribute indiziert, was das erste Parsing und die Aktualisierung ebenfalls beschleunigt hat, aber es ist immer noch langsam (die obigen Zahlen beziehen sich auf die Indizierung). Was mir aufgefallen ist, dass sich das Parsen/Aktualisieren allmählich verlangsamt. Während anfänglich schnell, wird es immer langsamer, da immer mehr Platten bearbeitet werden.

Meine Frage ist also, ob irgendetwas Vorschläge für mich hat, wie ich die Geschwindigkeit verbessern könnte, mit der ich meinen Datensatz aktualisiere? Ich verwende MagicalRecord zum Abrufen des Datensatzes. Hier ist der Code:

Record *record; 
if (!isUpdate) { 
    record = [NSEntityDescription insertNewObjectForEntityForName:@"Record" inManagedObjectContext:backgroundContext]; 
} else { 
    NSPredicate *recordPredicate = [NSPredicate predicateWithFormat:@"SELF.tag == %@", [[node attributeForName:@"tag"] stringValue]]; 
    record = [Record findFirstWithPredicate:recordPredicate]; 
} 
+0

Wie oft rufst du den Kontext auf? –

+0

Ich nenne es insgesamt 18 Mal. Ich habe mit dieser Nummer herumgespielt und es scheint die magische Zahl für die Gesamtgeschwindigkeit zu sein. – runmad

+0

Wenn ich das richtig lese, dauert es beim ersten Einlegen dieser Aufzeichnungen nur etwa 8 Sekunden. Ist es also naiv zu glauben, dass wenn Sie die bestehende Entität löschen, dann fügen Sie eine neue mit den aktualisierten Daten ein, die schneller ist? –

Antwort

3

Anstatt Tonnen von Abrufen zu tun, machen Sie eine Abfrage für jeden Entitätstyp und speichern Sie sie in einem Wörterbuch nach Tag, dann überprüfen Sie einfach das Wörterbuch, wenn es ein Objekt mit diesem Schlüssel gibt. Sie sollten in der Lage sein, die Eigenschaft "ToToFetch" so festzulegen, dass nur das Tag eingeschlossen wird. Dies sollte den Overhead reduzieren.

+0

Das wäre genau mein Ansatz, ich verstehe nicht, warum Find-or-Create hier keine Rolle spielen würde, ist es nicht DAS Szenario wo finde-und -create gilt? – codeclash

+0

Nein, ist es nicht. Find- * oder * -create zählt, wenn Sie einen vollständigen Datensatz einfügen müssen, der nicht existiert. In meinem Fall muss ich den Datensatz bei Bedarf aktualisieren. Also würde ich beide einen neuen Datensatz einfügen müssen, wenn der XML-Feed einen neuen Datensatz hat, aber für jeden einzelnen Datensatz, der sich bereits in der Datenbank befindet, müsste ich seine Eigenschaften aktualisieren. – runmad

+0

Überprüfen wir: Ist es wahr, dass Sie für jedes Element in Ihrem frischen XML den "Tag" verwenden, eine Abrufanforderung über alle Elemente im Hauptdatenspeicher ausführen, um zu prüfen, ob es bereits ein solches Element gibt, falls ja, aktualisieren dass, wenn nicht, einfügen? Ist es dann nicht wahr, dass Sie grundsätzlich eine Abrufanforderung für JEDES Element in Ihrem neuen XML-Dokument ausführen? Wenn ja, würden Sie NUR einen einzigen Abruf durchführen wollen (um ein NSDictionary (Schlüssel = "Tag", value = Item) aller existierenden Elemente im persistenten Speicher zu erhalten und das NSDictionary nach vorhandenen zu durchsuchen (und sie zu aktualisieren), spart das in Chargen), und fügt neue nur ein, wenn nicht gefunden? – codeclash

1

Eine Sache, die Sie versuchen könnten, würde eine Vorlage NSPredicate verwenden, so dass Sie nicht wieder Parsen das Format-String für jeden finden/holen, dass Sie tun.

Also, bevor Sie Ihre Schleife eingeben:

NSPredicate *template = [NSPredicate predicateWithFormat:@"SELF.tag == $RECORD_TAG"]; 

innerhalb der Schleife:

Record *record; 
if (!isUpdate) { 
    record = [NSEntityDescription insertNewObjectForEntityForName:@"Record" inManagedObjectContext:backgroundContext]; 
} else { 
    NSPredicate *recordPredicate = []; 
    record = [Record findFirstWithPredicate:[template predicateWithSubstitutionVariables:[NSDictionary dictionaryWithObject:[[node attributeForName:@"tag"] stringValue] forKey:@"RECORD_TAG"]]; 
} 

See Apple Predicate Programming Guide für weitere Informationen.

+0

half ein winziges bisschen. Ich habe das eigentlich für ~ 98% der Objekte gemacht (es gibt verschiedene Arten), und mache es jetzt mit den restlichen. Habe mir ca. 2 Sekunden aus den bisherigen 144 Sekunden gerettet :) – runmad

1

Sie könnten auch eine Kombination von Senior's Antwort mit Hashing der Eigenschaften versuchen.

Beim Einfügen Hash-Eigenschaften und speichern Sie diesen Hash als eine Art Prüfsummen-Eigenschaft der Record.
Bei Aktualisierung legen Sie die abgerufenen Eigenschaften als Tag und Prüfsumme fest und führen einen Abruf aller Elemente durch. Wenn Sie dann über Ihren Datensatz iterieren, wenn die Prüfsumme von der Abfrage abweicht, können Sie diese Record abrufen und aktualisieren.

1

Die erste Antwort auf ALLE Leistungsprobleme ist das Ausführen von Instrumenten. Mit diesen Daten können Sie Ihre Problembereiche identifizieren. Von da an können Sie weitere spezifische Fragen zu bestimmten Aspekten der Leistungsverbesserung haben.

Wir Menschen sind notorisch schlecht darin, Leistungsengpässe zu identifizieren. Also, benutze zuerst die Instrumente. Es wird Ihnen sicherlich sagen, wo Ihre Zeit verbracht wird.

Verwandte Themen