Хоча на це питання вже відповіли, я подумав, що можу зазвучити дві копійки.
ВІДХОДЖЕННЯ : Я працював у ESRI в команді GeoDatabase кілька років і відповідав за підтримку різних частин коду GeoDatabase (Версія, Курсори, Редагування, Історія, Класи стосунків тощо).
Я думаю, що найбільшим джерелом проблем продуктивності коду ESRI є не розуміння наслідків використання різних об'єктів, зокрема, "маленьких" деталей різних абстракцій GeoDatabase! Тому дуже часто розмова переходить на мову, яка використовується як винуватця виступу. У деяких випадках це може бути. Але не весь час. Почнемо з мовної дискусії та відпрацюємо свій шлях назад.
1. - Мова програмування, яку ви вибираєте, має значення лише тоді, коли ви робите щось складне, у вузькому циклі. Здебільшого це не так.
Великий слон у кімнаті полягає в тому, що в основі всього коду ESRI у вас є ArcObjects - і ArcObjects пишеться на C ++ за допомогою COM . Комунікація з цим кодом коштує. Це справедливо для C #, VB.NET, python або будь-якого іншого, що ви використовуєте.
Ви платите ціну при ініціалізації цього коду. Це може бути незначною вартістю, якщо ви це зробите лише один раз.
Потім ви платите ціну за кожен наступний раз, коли ви взаємодієте з ArcObjects.
Особисто я схильний писати код для своїх клієнтів в C #, тому що це досить легко і швидко. Однак кожен раз, коли мені хочеться перемістити дані або зробити якусь обробку для великої кількості даних, яка вже реалізована в Geoprocessing, я просто ініціалізую підсистему сценаріїв і передаю свої параметри. Чому?
- Це вже реалізовано. То навіщо винаходити колесо?
- Це насправді може бути швидше . "Швидше, ніж писати це на C #?" Так! Якщо я реалізую, скажімо, завантаження даних вручну, це означає, що я плачу ціну на переключення контексту .NET у жорсткий цикл. Кожна GetValue, Insert, ShapeCopy має вартість. Якщо я здійснив один виклик в GP, то весь процес завантаження даних відбудеться в реальній реалізації GP - в C ++ в середовищі COM. Я не плачу ціну за переключення контексту, тому що її немає - а значить, вона швидша.
Ага так, тож тоді рішення, якщо використовувати багато функцій геообробки. Насправді треба бути обережними.
2. GP - це чорна скринька, яка копіює дані (можливо, зайві) навколо
Це меч з двома кінцями. Це чорна скринька, яка робить деяку магію всередині і випльовує результати - але ці результати дуже часто дублюються. 100000 рядків можна легко перетворити на 1 000 000 рядків на диску, коли ви запустили свої дані через 9 різних функцій. Використовувати лише функції GP - це як створити лінійну модель GP, і добре ...
3. Зв'язати занадто багато функцій GP для великих наборів даних вкрай неефективно. Модель GP - це (потенційно) еквівалентна виконанню запиту по-справжньому насправді дуже німим способом
Тепер не зрозумійте мене неправильно. Я люблю моделі GP - це рятує мене від написання коду весь час. Але я також усвідомлюю, що це не найефективніший спосіб обробки великих наборів даних.
Ви коли-небудь чули про планувальник запитів ? Його завдання полягає в тому, щоб подивитися на оператор SQL, який ви хочете виконати, генерувати план виконання у вигляді спрямованого графіка, який схожий на чорт, як у моделі GP , переглянути статистику, що зберігається в db, і вибрати найбільш оптимальний порядок їх виконання . GP просто виконує їх у порядку, коли ви розміщуєте речі, оскільки у нього немає статистичних даних, щоб зробити щось більш розумно - ви планувальник запитів . І вгадайте, що? Порядок, коли ви виконуєте речі, дуже залежить від вашого набору даних. Порядок, в якому ви виконуєте речі, може змінювати дні та секунди, і саме ви вирішувати.
"Чудово" ви говорите, я не буду сценаріювати речі сам і буду уважніше, як пишу речі. Але ви розумієте абстракції бази даних GeoDatabase?
4.Не розуміючи абстракцій GeoDatabase, можна легко вас вкусити
Замість того, щоб вказувати на кожну річ, яка, можливо, може створити вам проблему, дозвольте лише зазначити кілька поширених помилок, які я бачу весь час, та деякі рекомендації.
- Розуміння різниці між істинним / хибним для переробки курсорів . Цей крихітний маленький прапор, встановлений на істину, може швидше виконувати порядки виконання.
- Помістіть свою таблицю в LoadOnlyMode для завантаження даних. Навіщо оновлювати індекс на кожній вставці?
- Зрозумійте, що навіть хоча IWorkspaceEdit :: StartEditing виглядає однаково у всіх робочих просторах, вони є різними звірами у кожному джерелі даних. У Enterprise GDB у вас може бути версія або підтримка транзакцій. Для форм-файлів це доведеться реалізувати зовсім по-іншому. Як би ви реалізували Undo / Redo? Вам навіть потрібно це ввімкнути (так, це може змінити використання пам'яті).
- Різниця між пакетними операціями або операціями з одним рядком. Приклад: GetRow vs GetRows - це різниця між тим, як робити запит, щоб отримати один рядок, або виконати один запит, щоб отримати кілька рядків. Жорсткий цикл із закликом до GetRow означає жахливу ефективність, і він є винуватцем №1 у виконанні проблем
- Використовуйте UpdateSearchedRows
- Зрозумійте різницю між CreateRow та CreateRowBuffer . Величезна різниця в режимі вставки.
- Зрозумійте, що IRow :: Store та IFeature :: Store запускає надзвичайно важкі поліморфні операції. Це, мабуть, причина №2 винуватця дуже повільної роботи. Він не просто зберігає рядок, це метод, який гарантує, що ваша геометрична мережа в порядку, що редактор ArcMap отримує повідомлення про те, що рядка змінилася, і повідомляє про всі класи відносин, які мають щось спільне з цим рядком, перевірити, щоб зробити переконайтеся, що кардинальність є дійсною і т. д. Ви не повинні вставляти нові рядки за допомогою цього, ви повинні використовувати InsertCursor !
- Ви хочете (потрібно) зробити ці вставки в EditSession? Це робить величезну різницю, робиш ти чи ні. Деякі операції вимагають цього (і роблять все повільніше), але коли вам це не потрібно, пропустіть функції скасувати / повторити.
- Курсори - дорогі ресурси. Після того, як ви будете мати ручку до одного, ви гарантуєте, що ви будете мати послідовність та ізоляцію, і це має витрати.
- Кешуйте інші ресурси, наприклад підключення до бази даних (не створюйте та не руйнуйте посилання на робочу область) та ручки таблиці (кожен раз, коли ви відкриваєте чи закриваєте одну - потрібно прочитати кілька таблиць метаданих).
- Якщо розмістити FeatureClasses всередині та за його межами FeatureDataset, це значно змінить продуктивність. Це не означає як організаційну особливість!
5. І в останню чергу ...
Зрозумійте різницю між операціями, пов'язаними з входом / виводом та процесором
Я чесно думав про те, щоб розширити більше на кожному з цих предметів і, можливо, зробити серію записів у блозі, яка висвітлює кожну з цих тем, але список відсталих у моєму календарі просто ударив мене по обличчю і почав кричати на мене.
Мої два центи.