Хотя на этот вопрос уже был дан ответ, я подумал, что смогу перезвонить и дать свои два цента.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ : Я работал в ESRI в команде GeoDatabase в течение нескольких лет и отвечал за поддержку различных частей кода GeoDatabase (управление версиями, курсоры, EditSessions, история, классы отношений и т. Д. И т. Д.).
Я думаю, что основной источник проблем с производительностью в коде ESRI - не понимание последствий использования различных объектов, в частности, «маленьких» деталей различных абстракций GeoDatabase! Поэтому очень часто разговор переключается на язык, используемый в качестве виновника проблем с производительностью. В некоторых случаях это может быть. Но не все время. Давайте начнем с языковой дискуссии и вернемся назад.
1.- Язык программирования, который вы выбираете, имеет значение только тогда, когда вы делаете что-то сложное, в тесном цикле. В большинстве случаев это не так.
Большой слон в комнате - то, что в основе всего кода ESRI, у вас есть ArcObjects - и ArcObjects написан на C ++ с использованием COM . За связь с этим кодом взимается плата. Это верно для C #, VB.NET, Python или чего-либо еще, что вы используете.
Вы платите цену при инициализации этого кода. Это может быть незначительной стоимостью, если вы делаете это только один раз.
Затем вы платите цену за каждое последующее взаимодействие с ArcObjects.
Лично я склонен писать код для своих клиентов на C #, потому что он прост и достаточно быстр. Однако каждый раз, когда я хочу переместить данные или выполнить некоторую обработку больших объемов данных, которая уже реализована в геообработке, я просто инициализирую подсистему сценариев и передаю свои параметры. Зачем?
- Это уже реализовано. Так зачем изобретать велосипед?
- Это на самом деле может быть быстрее . "Быстрее, чем писать это на C #?" Да! Если я реализую, скажем, загрузку данных вручную, это означает, что я плачу за переключение контекста .NET в тесном цикле. Каждый GetValue, Insert, ShapeCopy имеет свою стоимость. Если я сделаю один вызов в GP, весь процесс загрузки данных будет происходить в реальной реализации GP - в C ++ в среде COM. Я не плачу за переключение контекста, потому что его нет - и, следовательно, это быстрее.
Ах да, так что тогда решение, если использовать множество функций геообработки. На самом деле, вы должны быть осторожны.
2. GP - это черный ящик, который копирует данные (потенциально без необходимости)
Это обоюдоострый меч. Это черный ящик, который совершает магию внутри и выдает результаты, но эти результаты очень часто дублируются. 100 000 строк могут быть легко преобразованы в 1 000 000 строк на диске после того, как вы проведете свои данные с помощью 9 различных функций. Использование только функций GP похоже на создание линейной модели GP, и хорошо ...
3. Объединение слишком большого количества функций GP для больших наборов данных крайне неэффективно. Модель GP (потенциально) эквивалентна выполнению запроса действительно очень тупым способом
Не поймите меня неправильно. Я люблю модели GP - это избавляет меня от написания кода все время. Но я также знаю, что это не самый эффективный способ обработки больших наборов данных.
Вы когда-нибудь слышали о Планировщике запросов ? Его задача - посмотреть на оператор SQL, который вы хотите выполнить, сгенерировать план выполнения в форме ориентированного графа, который выглядит во многом как модель GP , посмотреть статистику, хранящуюся в БД, и выбрать наиболее оптимальный порядок их выполнения . GP просто выполняет их в том порядке, в котором вы их размещаете, потому что у него нет статистики, чтобы делать что-то более разумно - вы - планировщик запросов . И угадайте, что? Порядок, в котором вы выполняете вещи, очень зависит от вашего набора данных. Порядок, в котором вы исполняете вещи, может иметь значение между днями и секундами, и вам решать.
«Отлично», говорите вы, я не буду писать сценарии сам и буду осторожен с тем, как пишу вещи. Но понимаете ли вы абстракции GeoDatabase?
4. Непонимание абстракций GeoDatabase может легко укусить вас
Вместо того, чтобы указывать на каждую вещь, которая может создать вам проблему, позвольте мне указать на несколько распространенных ошибок, которые я вижу постоянно, и некоторые рекомендации.
- Понимание различий между Истинным / Ложным для рециркуляции курсоров . Этот крошечный флажок, установленный в true, может на несколько порядков быстрее работать.
- Поместите вашу таблицу в LoadOnlyMode для загрузки данных. Зачем обновлять индекс при каждой вставке?
- Поймите, что, хотя IWorkspaceEdit :: StartEditing выглядит одинаково во всех рабочих пространствах, они очень разные звери в каждом источнике данных. На Enterprise GDB у вас может быть управление версиями или поддержка транзакций. На шейп-файлах это должно быть реализовано совсем другим способом. Как бы вы реализовали Undo / Redo? Вам даже нужно включить его (да, это может иметь значение в использовании памяти).
- Разница между пакетными операциями или операциями с одной строкой. Пример GetRow против GetRows - это разница между выполнением запроса для получения одной строки или выполнением одного запроса для извлечения нескольких строк. Тесная петля с вызовом GetRow означает ужасную производительность, и это виновник # 1 проблем с производительностью
- Используйте UpdateSearchedRows
- Понять разницу между CreateRow и CreateRowBuffer . Огромная разница во времени выполнения вставки.
- Поймите, что IRow :: Store и IFeature :: Store запускают сверхтяжелые полиморфные операции. Это, вероятно, причина № 2 виновника действительно низкой производительности. Он не просто сохраняет строку, это метод, который гарантирует, что ваша геометрическая сеть в порядке, что ArcMap Editor получает уведомление об изменении строки, которая уведомляет все классы отношений, которые имеют отношение к этой строке, чтобы подтвердить убедитесь, что количество элементов допустимо и т. д. Вы не должны вставлять новые строки с этим, вы должны использовать InsertCursor !
- Вы хотите (нуждаетесь) сделать эти вставки в EditSession? Это имеет огромное значение, если вы делаете или нет. Некоторые операции требуют этого (и замедляют работу), но когда вам это не нужно, пропустите функции отмены / возврата.
- Курсоры дорогие ресурсы. После того, как вы справитесь с ним, вам гарантируется, что вы будете иметь Последовательность и Изоляцию, и это будет стоить.
- Кэшируйте другие ресурсы, такие как соединения с базой данных (не создавайте и не уничтожайте вашу ссылку на рабочую область) и дескрипторы таблиц (каждый раз, когда вы открываете или закрываете одну из них - необходимо прочитать несколько таблиц метаданных).
- Помещение FeatureClasses внутри или вне FeatureDataset имеет огромное значение в производительности. Это не подразумевается как организационная особенность!
5. И последнее, и не в последнюю очередь ...
Понимать разницу между операциями, связанными с вводом / выводом
Я честно думал о расширении каждого из этих элементов и, возможно, о создании серии записей в блоге, которые охватывают каждую из этих тем, но список невыполненных работ моего календаря просто ударил меня по лицу и начал кричать на меня.
Мои два цента.