Obwohl diese Frage bereits beantwortet wurde, dachte ich, ich könnte meine zwei Cent einlösen.
HAFTUNGSAUSSCHLUSS : Ich habe einige Jahre für ESRI im GeoDatabase-Team gearbeitet und war für die Verwaltung verschiedener Teile des GeoDatabase-Codes (Versionierung, Cursors, EditSessions, Verlauf, Beziehungsklassen usw. usw.) verantwortlich.
Ich denke, die größte Ursache für Leistungsprobleme mit ESRI-Code ist, dass man die Auswirkungen der Verwendung verschiedener Objekte nicht versteht, insbesondere die "kleinen" Details der verschiedenen GeoDatabase-Abstraktionen! Sehr oft wechselt die Konversation zu der Sprache, die als Täter für die Leistungsprobleme verwendet wird. In einigen Fällen kann es sein. Aber nicht die ganze Zeit. Beginnen wir mit der Sprachdiskussion und arbeiten uns zurück.
1.- Die Programmiersprache, die Sie auswählen, spielt nur eine Rolle, wenn Sie komplizierte Aufgaben in einer engen Schleife ausführen. Meistens ist dies nicht der Fall.
Der große Elefant im Raum ist, dass Sie im Kern des gesamten ESRI-Codes ArcObjects haben - und ArcObjects mit COM in C ++ geschrieben wurde . Die Kommunikation mit diesem Code ist kostenpflichtig. Dies gilt für C #, VB.NET, Python oder was auch immer Sie verwenden.
Sie zahlen einen Preis bei der Initialisierung dieses Codes. Dies kann zu vernachlässigbaren Kosten führen, wenn Sie dies nur einmal tun.
Sie zahlen dann einen Preis für jede weitere Interaktion mit ArcObjects.
Persönlich neige ich dazu, Code für meine Kunden in C # zu schreiben, weil es einfach und schnell genug ist. Jedes Mal, wenn ich Daten verschieben oder eine Verarbeitung für große Datenmengen durchführen möchte, die bereits in der Geoverarbeitung implementiert sind, initialisiere ich einfach das Skriptsubsystem und übergebe meine Parameter. Warum?
- Es ist bereits implementiert. Warum also das Rad neu erfinden?
- Es kann tatsächlich schneller sein . "Schneller als in C # schreiben?" Ja! Wenn ich das Laden von Daten beispielsweise manuell implementiere, bedeutet dies, dass ich den Preis für die .NET-Kontextumschaltung in einer engen Schleife zahle. Für jedes GetValue, Insert und ShapeCopy fallen Kosten an. Wenn ich den einen Aufruf in GP durchführe, geschieht der gesamte Datenladeprozess in der tatsächlichen Implementierung von GP - in C ++ innerhalb der COM-Umgebung. Ich zahle nicht den Preis für Kontextwechsel, weil es keine gibt - und daher ist es schneller.
Ah ja, also dann die Lösung, wenn viele Geoverarbeitungsfunktionen verwendet werden sollen. Eigentlich muss man vorsichtig sein.
2. GP ist eine Blackbox, die Daten (möglicherweise unnötig) kopiert
Es ist ein zweischneidiges Schwert. Es handelt sich um eine Black Box, die intern etwas zaubert und Ergebnisse ausspuckt - aber diese Ergebnisse werden sehr oft dupliziert. 100.000 Zeilen können problemlos in 1.000.000 Zeilen auf der Festplatte konvertiert werden, nachdem Sie Ihre Daten über 9 verschiedene Funktionen ausgeführt haben. Die Verwendung von GP-Funktionen entspricht der Erstellung eines linearen GP-Modells.
3. Die Verkettung zu vieler GP-Funktionen für große Datenmengen ist äußerst ineffizient. Ein GP-Modell ist (potentiell) gleichbedeutend mit einer wirklich sehr, sehr dummen Ausführung einer Abfrage
Versteh mich jetzt nicht falsch. Ich liebe GP Models - das erspart mir das ständige Schreiben von Code. Mir ist aber auch bewusst, dass es nicht die effizienteste Art ist, große Datensätze zu verarbeiten.
Haben Sie schon einmal von einem Abfrageplaner gehört ? Ihre Aufgabe ist es, die SQL-Anweisung zu überprüfen, die Sie ausführen möchten, einen Ausführungsplan in Form eines gerichteten Diagramms zu generieren , das einem GP-Modell sehr ähnlich sieht , die in der Datenbank gespeicherten Statistiken zu überprüfen und die meisten auszuwählen optimale Reihenfolge, um sie auszuführen . GP führt sie nur in der Reihenfolge aus, in der Sie sie abgelegt haben, weil es keine Statistiken gibt, mit denen Sie intelligenter vorgehen können - Sie sind der Abfrageplaner . Und rate was? Die Reihenfolge, in der Sie die Dinge ausführen, hängt stark von Ihrem Datensatz ab. Die Reihenfolge, in der Sie die Dinge ausführen, kann den Unterschied zwischen Tagen und Sekunden ausmachen, und die Entscheidung liegt bei Ihnen.
"Großartig", sagst du, ich schreibe die Dinge nicht selbst und achte darauf, wie ich Sachen schreibe. Aber verstehen Sie GeoDatabase-Abstraktionen?
4.Unverständliche GeoDatabase-Abstraktionen können Sie leicht beißen
Anstatt auf jede einzelne Sache hinzuweisen, die Ihnen möglicherweise Probleme bereiten kann, möchte ich auf einige häufige Fehler hinweisen, die ich ständig sehe, sowie auf einige Empfehlungen.
- Verstehen des Unterschieds zwischen True / False für das Recycling von Cursorn . Dieses winzige kleine Flag, das auf true gesetzt ist, kann die Laufzeit um Größenordnungen beschleunigen.
- Versetzen Sie Ihre Tabelle in LoadOnlyMode für Datenladevorgänge . Warum sollte der Index für jede Beilage aktualisiert werden?
- Verstehen Sie, dass IWorkspaceEdit :: StartEditing zwar in allen Arbeitsbereichen gleich aussieht, es sich jedoch bei jeder Datenquelle um sehr unterschiedliche Bestien handelt. In einer Enterprise GDB verfügen Sie möglicherweise über eine Versionierung oder Unterstützung für Transaktionen. In Shapefiles muss es auf eine ganz andere Art und Weise implementiert werden. Wie würden Sie Undo / Redo implementieren? Müssen Sie es überhaupt aktivieren (ja, es kann sich auf die Speichernutzung auswirken)?
- Der Unterschied zwischen Stapeloperationen oder Einzelzeilenoperationen. Fallbeispiel GetRow vs GetRows - Dies ist der Unterschied zwischen einer Abfrage, um eine Zeile abzurufen, oder einer Abfrage, um mehrere Zeilen abzurufen. Eine enge Schleife mit dem Aufruf von GetRow bedeutet schreckliche Leistung und ist der Hauptgrund für Leistungsprobleme
- Verwenden Sie UpdateSearchedRows
- Verstehen Sie den Unterschied zwischen CreateRow und CreateRowBuffer . Enormer Unterschied in der Insert-Laufzeit.
- Verstehen Sie, dass IRow :: Store und IFeature :: Store extrem schwere polymorphe Operationen auslösen . Dies ist wahrscheinlich der Grund # 2 für die sehr langsame Leistung. Es wird nicht nur die Zeile gespeichert. Mit dieser Methode wird sichergestellt, dass Ihr geometrisches Netzwerk in Ordnung ist. Der ArcMap-Editor wird darüber informiert, dass sich eine Zeile geändert hat. Außerdem werden alle Beziehungsklassen benachrichtigt, die etwas mit dieser Zeile zu tun haben Stellen Sie sicher, dass die Kardinalität gültig ist usw. Sie sollten keine neuen Zeilen damit einfügen, Sie sollten einen InsertCursor verwenden !
- Möchten (müssen) Sie diese Einfügungen in einer EditSession vornehmen? Es macht einen großen Unterschied, ob Sie es tun oder nicht. Bei einigen Vorgängen ist dies erforderlich (und es wird langsamer). Wenn dies jedoch nicht erforderlich ist, überspringen Sie die Funktionen zum Rückgängigmachen / Wiederherstellen.
- Cursor sind teure Ressourcen. Sobald Sie ein Handle zu einem haben, werden Sie garantiert, dass Sie Konsistenz und Isolation haben und das hat Kosten.
- Zwischenspeichern Sie andere Ressourcen wie Datenbankverbindungen (erstellen und zerstören Sie nicht Ihre Workspace-Referenz) und Tabellenhandles (jedes Mal, wenn Sie eine öffnen oder schließen, müssen mehrere Metadatentabellen gelesen werden).
- Das Platzieren von FeatureClasses innerhalb oder außerhalb eines FeatureDatasets macht einen großen Unterschied in der Leistung aus. Es ist nicht als organisatorisches Merkmal gedacht!
5.Und zu guter Letzt ...
Verstehen Sie den Unterschied zwischen E / A-gebundenen und CPU-gebundenen Vorgängen
Ich habe ehrlich gesagt darüber nachgedacht, mehr über jedes einzelne dieser Elemente zu erfahren und vielleicht eine Reihe von Blogeinträgen zu erstellen, die sich mit jedem einzelnen dieser Themen befassen, aber die Backlog-Liste meines Kalenders schlug mir nur ins Gesicht und fing an, mich anzuschreien.
Meine zwei Cent.