Компилировать скрипты Python (в .exe), которые используют Инструменты геообработки ArcGIS?

12

Я работаю с Python уже несколько месяцев и разработал несколько достаточно сложных скриптов для задач геообработки. Тем не менее, я все еще многому учусь, поскольку исходил из опыта работы с SQL / VBA / VBScript.

Я знаю, что скомпилированный код обычно работает быстрее, чем код, который должен обрабатывать языковой интерпретатор, поэтому меня интересует возможность компиляции скрипта геообработки Python в файл .EXE для работы с большими данными.

Это вообще возможно? Если это так, как лучше всего скомпилировать скрипт Python (.py), который импортирует модули arcgisscripting или arcpy?

Я потратил несколько минут, пытаясь найти то, что я хочу сделать, и поиск дал эту статью среди других: http://www.ehow.com/how_2091641_compile-python-code.html

Компилятор, казалось, работал, но после выполнения полученного файла .EXE он дал загадочную ошибку, сообщив, что некоторые файлы были недоступны.

Скрипт Python запускает то, что кажется достаточно хорошим из командной строки, но мне интересно, смогу ли я увидеть небольшое улучшение, если бы смог скомпилировать файл .py. Опять же, я работаю с некоторыми большими наборами данных, на обработку которых уходит +20 часов (разграничение водоразделов на участках отбора проб качества воды). Я возьму все, что смогу улучшить.

Сценарий выполнялся на 10% быстрее вне ArcGIS из командной строки с использованием тестового набора сайтов по сравнению с настройкой сценария в качестве инструмента-скрипта на новой панели инструментов в ArcCatalog. Я запускал скрипт из командной строки без любого экземпляра ArcGIS, открытого на выделенной машине.

Итак, возможно ли скомпилировать скрипты Python, которые импортируют модуль arcgisscripting и которые вызывают инструменты ArcToolBox?

РЕДАКТИРОВАТЬ

Спасибо за вклад, это полезно для меня. Сценарий в значительной степени является способом координации ряда инструментов ArcGIS и вывода в желаемых форматах / местах / с соответствующей атрибуцией. Я уже обрезал некоторые толстые, я думаю, записав в пустую папку вместо чистой персональной базы геоданных некоторые промежуточные растровые файлы, чтобы они могли быть сохранены в формате ESRI GRID по сравнению с форматом IMG. Я проверю предложения профилировщика все же.

В моем офисе есть некоторые, кто спрашивает Python, что «этот скомпилированный код намного быстрее, чем код, выполняемый через интерпретатор», в основном по сравнению, скажем, с скомпилированной программой Visual Basic или программой VB.NET, но это хороший момент, который инструменты будут занимать время в любом случае. И, похоже, что в современных вычислительных машинах интерпретируемый код может быть не намного медленнее, чем скомпилированный код, чтобы оправдать эту лишнюю милю.

РЕДАКТИРОВАТЬ - обновление по оптимизации программы с растровыми форматами.

Хотел следить за моей «оптимизацией» этой программы на Python, и я смог сократить время обработки на 2 часа, записав временные растры в формат GRID вместо личной базы геоданных. Мало того, что произошло существенное сокращение потребления дискового пространства размера данных. Первоначальный прогон, который я написал для всех растров (а они были только точечными объектами, преобразованными в растры, а затем растровые поверхности), позволил получить 37,1 ГБ данных только для этих файлов. Запись последних двух выходных данных в папку в формате GRID была уменьшена до 667 МБ данных.

Мне было бы любопытно посмотреть, как файловая GDB будет обрабатывать эти данные, хотя в основном по размеру данных. Но сокращение моего времени обработки с 9,5 часов до 7,5 часов, безусловно, достаточно для защиты от работы с растрами вне баз геоданных в формате GRID.

turkishgold
источник
Это утро ArcGIS Server Blog очень своевременно. Стерлинг @ Эсри хорошо объясняет, почему и когда [здесь.] [1] [1]: blogs.esri.com/Dev/blogs/arcgisserver/archive/2011/04/12/…
Брэд Несом

Ответы:

15

Первый вопрос: сколько из этого вы делаете в Python? Вы просто обращаетесь к инструментам геообработки или выполняете значительный объем численного анализа в Python? Если первое, узкие места, скорее всего, существуют в инструментах, и использование собственного кода в вашем скрипте не принесет вам столько же, сколько другие умные обходные пути. Если последнее, то, возможно, вы захотите найти что-то медленное и сделать это быстрее с помощью лучших алгоритмов, или, возможно, с тупым, или каким-либо другим вариантом, как описано ниже.

py2exe фактически не компилирует ваш код в нативный x86 / x64, он просто предоставляет исполняемый файл, который встраивает ваш скрипт в виде байт-кода и предоставляет в основном переносимый способ его распространения пользователям без Python в их системах. Не удалось при попытке связать arcgisscripting, поэтому он не работал. На самом деле, заставить работать py2exe все равно не повлияет на производительность.

Я настоятельно рекомендую вам сначала использовать профилировщик, чтобы идентифицировать медленные биты и оптимизировать их. В Python встроен очень хороший набор, в долгосрочной перспективе используйте cProfile, чтобы найти потенциальные места, чтобы сделать его быстрее. Оттуда вы можете оптимизировать на разделы в пользовательских C или , возможно , поэкспериментировать с небольшими порциями , как Cython модулей .pyx.

Вы можете заглянуть в Cython для возможного построения всего сценария Python как модуля расширения собственного кода, но Psyco также может дать вам повышение производительности с меньшим барьером для входа.

Джейсон Шайрер
источник
4

Сколько времени занимает разграничение водораздела при запуске из стандартных инструментов в ArcToolbox по сравнению с версией скрипта? Если времена будут похожи, то я подозреваю, что улучшений не будет. Возможно, вы захотите запустить длинные процессы в фоновом режиме за пределами ArcMap.


источник
Я уточнил свой первоначальный вопрос и надеюсь, что получу утвердительный ответ «да / нет», можно ли скомпилировать такой код, поскольку этот ответ не отвечает на мой вопрос.
turkishgold
2
@turkish Это может не ответить на ваш вопрос напрямую, но это отличное предложение. Скорее всего, ваш процесс тратит все свое время на разграничение, поэтому никакие изменения кода не помогут заметно. Тем не менее, пересмотр алгоритма может иметь огромное значение. Поэтому первое, что вы хотите сделать, - это профилировать текущее выполнение, чтобы увидеть, не тратите ли вы свое время с этим подходом к компиляции.
whuber
1
Я согласен с @Dan и @whuber. Я думаю, что проведение более глубокого анализа (т.е. бенчмаркинга и профилирования) даст гораздо лучшее представление об улучшениях производительности, чем просто метод компиляции всего методом грубой силы.
Джейсон Шайрер,
4

Не используйте личную базу геоданных без уважительной причины. По нашему опыту, они значительно медленнее, чем все другие формы хранения данных esri ( ссылка ). Хотя я прочитал один отчет здесь на GIS.se, который видел личный быстрее, чем файл GDB.

Когда рабочий процесс состоит из множества маленьких итераций, вызов для создания геопроцессора и получения лицензии часто является наиболее дорогостоящей частью использования python. Поэтому я стараюсь делать как можно больше впереди или сзади gp = ...(или import arcpyв v10).

Что касается компиляции, эта цитата говорит лучше всего:

Стоит отметить , что во время работы скомпилированного [питон] сценарий имеет более быстрый запуск времени (как это не нужно компилировать), не работать быстрее.

У Марка Седерхольма есть презентация об использовании ArcObjects в Python с некоторой статистикой операций шейпопирования (слайд № 4). Python не очень хорошо справляется: 32% от того, чего можно достичь с помощью C ++ (VBA составил 92%, VB & C # - 48%). Не бегайте и не кричите слишком быстро, многие инструменты геообработки в любом случае являются скриптами на python (поиск c: \ program files \ arcgis \ для '* .py').

Как уже говорили многие в других местах, с python время, затрачиваемое на оптимизацию производительности путем компиляции или написания основной функции C или C ++, часто затмевает любой фактический прирост производительности (возможно), достигнутый во время выполнения. Многие говорят, что главным преимуществом Python является оптимизация и улучшение времени разработки ; человеческое внимание гораздо ценнее и дороже, чем время машинной обработки.

Мэтт Уилки
источник
1
Да, по всем пунктам. За мои деньги оптимальное использование времени разработчика - это создание прототипа * в тесте Python, переход на C / C ++ для оптимизации узких мест. * Я говорю «прототип», но я знаю, что в 95% случаев «прототип» готовится к производству.
Джейсон Шейрер,
Замечательные комментарии и спасибо за ссылки на ArcObjects в Python. Я думаю, что запись в GDB имеет преимущества с точки зрения управления данными по сравнению с шейп-файлом (ограничения таблицы атрибутов в шейп-файлах по сравнению с классами объектов, представление геометрии, общие методы управления данными и т. Д.), А также с вещами, которые вы можете сделать намного проще и чище в среда доступа и работа с файлами DBF. Итак, в основном компромисс между затратами и выгодами и тем, что вы делаете, и что вы собираетесь делать с выходными данными. Срединная основа растров за пределами GDB и всего остального в GDB, кажется, работает.
turkishgold
1

Вы не можете скомпилировать код Python в машинный код. Когда он запускается в первый раз, он компилируется в 'bytecode', промежуточный язык (который создает файлы pyc)

py2exe упаковывает dll-файлы, требуемые интерпретатором, и все необходимые python-файлы / внешние файлы в исполняемый файл. Он не скомпилирован - время выполнения не должно сильно отличаться.

Возможно заставить код Python работать очень быстро, используя комбинацию различных методов.

Первое, что вы должны сделать, это профилировать свой код, чтобы найти узкие места. После обнаружения я обычно использую этот процесс:

  • Удалите циклы for, используя numy-массивы или функцию map (). Это в основном толкает петлю в C.
  • Изучите лучшие реализации алгоритма (этот вид идет параллельно с вышеупомянутым). Такие вещи, как сокращение числа операций ввода-вывода, обеспечение доступа к данным / их хранения в смежных блоках.
  • Уловки интерпретатора, такие как избегание дорогостоящих поисков внутри циклов, избегание блоков if в циклах (вместо этого используйте try)
  • Профиль снова
  • Если он все еще слишком медленный, посмотрите на загрузку критических частей в C с помощью Cython (или написание непосредственно в C, создание dll и использование ctypes для его вызова)
  • Профиль снова
  • Если все еще слишком медленно, посмотрите на параллельные вычисления или вычисления на GPU (многопроцессорная библиотека, pyCUDA, ParallelPython и т. Д.)
Джеймс
источник
0

Если вы импортируете скрипт Python из другого места, он генерирует файл .pyc. Таким образом, один простой способ проверить, имеет ли смысл компиляция, состоит в том, чтобы превратить ваш скрипт в функцию (например, main ()). Если вы сохраните этот скрипт как, example.pyтогда создайте другой файл со следующими строками:

import example
example.main() # call your script(s)

Если вы выполняете время изнутри скрипта и запускаете его при импорте, возможно, вы видите разницу. Это низкотехнологичный способ сделать это все же.

djq
источник