Chociaż na to pytanie już udzielono odpowiedzi, pomyślałem, że mogę wrzucić dwadzieścia centów.
ZASTRZEŻENIE : Pracowałem dla ESRI w zespole GeoDatabase przez kilka lat i byłem odpowiedzialny za utrzymanie różnych części kodu GeoDatabase (wersjonowanie, kursory, edycja sesji, historia, klasy relacji itp.).
Myślę, że największym źródłem problemów z wydajnością kodu ESRI nie jest zrozumienie implikacji używania różnych obiektów, w szczególności „małych” szczegółów różnych abstrakcji GeoDatabase! Bardzo często rozmowa przełącza się na język używany jako sprawca problemów z wydajnością. W niektórych przypadkach może tak być. Ale nie cały czas. Zacznijmy od dyskusji na temat języka i cofnijmy się.
1.- Wybrany język programowania ma znaczenie tylko wtedy, gdy robisz coś skomplikowanego, w ciasnej pętli. W większości przypadków tak nie jest.
Duży słoń w pokoju polega na tym, że u podstaw całego kodu ESRI znajdują się ArcObjects - a ArcObjects jest napisane w C ++ przy użyciu COM . Komunikowanie się z tym kodem kosztuje. Odnosi się to do C #, VB.NET, python lub czegokolwiek innego używasz.
Płacisz cenę przy inicjalizacji tego kodu. Może to być nieistotny koszt, jeśli zrobisz to tylko raz.
Następnie płacisz cenę za każde kolejne interakcje z ArcObjects.
Osobiście mam tendencję do pisania kodu dla moich klientów w języku C #, ponieważ jest to łatwe i wystarczająco szybkie. Jednak za każdym razem, gdy chcę przenosić dane lub przetwarzać duże ilości danych, które są już zaimplementowane w Geoprocessing , po prostu inicjuję podsystem skryptów i przekazuję moje parametry. Czemu?
- Jest już zaimplementowany. Po co więc wymyślać koło?
- To może być rzeczywiście szybsze . „Szybsze niż pisanie w C #?” Tak! Jeśli zaimplementuję, powiedzmy, ładowanie danych ręcznie, oznacza to, że płacę cenę przełączania kontekstu .NET w ścisłej pętli. Każde GetValue, Insert, ShapeCopy ma swój koszt. Jeśli wykonam jedno wywołanie w GP, cały proces ładowania danych nastąpi w rzeczywistej implementacji GP - w C ++ w środowisku COM. Nie płacę ceny za zmianę kontekstu, ponieważ jej nie ma - i dlatego jest szybsza.
Ach tak, więc rozwiązaniem jest użycie wielu funkcji geoprzetwarzania. Właściwie musisz być ostrożny.
2. GP to czarna skrzynka, która kopiuje dane (potencjalnie niepotrzebnie)
Jest to miecz obosieczny. Jest to czarna skrzynka, która wykonuje trochę magii wewnętrznie i wypluwa wyniki - ale te wyniki są bardzo często powielane. 100 000 wierszy można łatwo przekonwertować na 1 000 000 wierszy na dysku po uruchomieniu danych przez 9 różnych funkcji. Używanie tylko funkcji GP jest jak tworzenie liniowego modelu GP i dobrze ...
3. Łączenie zbyt wielu funkcji GP dla dużych zestawów danych jest wysoce nieefektywne. Model GP jest (potencjalnie) równoważny do wykonania zapytania w naprawdę naprawdę głupi sposób
Nie zrozum mnie źle. Uwielbiam modele GP - oszczędza mi to ciągłego pisania kodu. Ale mam również świadomość, że nie jest to najbardziej wydajny sposób przetwarzania dużych zbiorów danych.
Czy wszyscy słyszeliście o narzędziu do planowania zapytań ? Jego zadaniem jest spojrzenie na instrukcję SQL, którą chcesz wykonać, wygenerowanie planu wykonania w postaci ukierunkowanego wykresu, który wygląda jak model GP , spojrzenie na statystyki przechowywane w bazie danych i wybranie najbardziej optymalna kolejność ich wykonania . GP po prostu wykonuje je w kolejności, w jakiej je umieściłeś, ponieważ nie ma statystyk, aby zrobić cokolwiek bardziej inteligentnie - jesteś planistą zapytań . I zgadnij co? Kolejność wykonywania rzeczy jest bardzo zależna od zestawu danych. Kolejność wykonywania rzeczy może mieć znaczenie między dniami i sekundami i to od Ciebie zależy.
„Świetnie”, mówisz, nie będę sam pisać scenariuszy i będę uważał na to, jak piszę. Ale czy rozumiesz abstrakcje GeoDatabase?
4. Niezrozumienie abstrakcji GeoDatabase może cię łatwo ugryźć
Zamiast wskazywać każdą rzecz, która może sprawić ci problem, pozwól mi tylko wskazać kilka typowych błędów, które widzę cały czas, i kilka rekomendacji.
- Zrozumienie różnicy między kursorem True / False for Recycling . Ta niewielka mała flaga ustawiona na true może przyspieszyć rzędy czasu działania.
- Umieść tabelę w LoadOnlyMode dla ładowań danych. Po co aktualizować indeks na każdej wkładce?
- Zrozum, że chociaż IWorkspaceEdit :: StartEditing wygląda tak samo we wszystkich obszarach roboczych, są one bardzo różnymi bestiami w każdym źródle danych. W Enterprise GDB możesz mieć wersję lub obsługę transakcji. W plikach kształtu będzie musiał zostać zaimplementowany w zupełnie inny sposób. Jak wdrożyłbyś Cofnij / Ponów? Czy w ogóle musisz go włączyć (tak, może to zmienić użycie pamięci).
- Różnica między operacjami wsadowymi lub operacjami jednorzędowymi. Sprawa w punkcie GetRow vs GetRows - jest to różnica pomiędzy robi kwerendę, aby uzyskać jeden wiersz lub wykonując jedną kwerendę, aby pobrać wiele wierszy. Ścisła pętla z wezwaniem do GetRow oznacza straszną wydajność i jest winowajcą nr 1 problemów z wydajnością
- Użyj UpdateSearchedRows
- Zrozum różnicę między CreateRow i CreateRowBuffer . Ogromna różnica w czasie wykonywania wstawiania.
- Zrozum, że IRow :: Store i IFeature :: Store wyzwalają bardzo ciężkie operacje polimorficzne . Jest to prawdopodobnie powód nr 2 sprawcy naprawdę niskiej wydajności. Nie tylko zapisuje wiersz, jest to metoda, która upewnia się, że twoja sieć geometryczna jest w porządku, że ArcMap Editor zostaje powiadomiony o zmianie wiersza, który powiadamia wszystkie klasy relacji, które mają cokolwiek wspólnego z tym wierszem, aby sprawdzić poprawność upewnij się, że liczność jest poprawna itp. Nie powinieneś wstawiać przy tym nowych wierszy, powinieneś używać InsertCursor !
- Czy chcesz (potrzebujesz) wykonać te wstawki w sesji edycji? To robi ogromną różnicę, jeśli tak, czy nie. Niektóre operacje tego wymagają (i spowalniają pracę), ale jeśli nie potrzebujesz, pomiń funkcje cofania / ponawiania.
- Kursory to drogie zasoby. Kiedy już będziesz miał do tego rękojeść, masz gwarancję, że będziesz miał spójność i izolację, a to będzie kosztować.
- Buforuj inne zasoby, takie jak połączenia z bazą danych (nie twórz i nie niszcz odwołania do obszaru roboczego) i uchwyty tabel (za każdym razem, gdy je otwierasz lub zamykasz - trzeba odczytać kilka tabel metadanych).
- Umieszczenie FeatureClasses wewnątrz lub na zewnątrz FeatureDataset robi ogromną różnicę w wydajności. Jest to nie oznaczało, jako element porządkujący!
5. I na koniec ...
Zrozumienie różnicy między operacjami związanymi z operacjami we / wy i procesorami
Szczerze, myślałem o rozszerzeniu każdego z tych elementów i być może zrobieniu serii wpisów na blogu, które obejmują każdy z tych tematów, ale lista zaległości mojego kalendarza właśnie uderzyła mnie w twarz i zaczęła na mnie krzyczeć.
Moje dwa centy.