¿Compilando scripts de Python (a .exe) que usan las herramientas de geoprocesamiento de ArcGIS?


12

Llevo varios meses codificando con Python y he desarrollado algunos scripts razonablemente complejos para tareas de geoprocesamiento principalmente. Dicho esto, todavía estoy aprendiendo mucho ya que provengo de un fondo SQL / VBA / VBScript.

Sé que el código compilado generalmente se ejecuta más rápido que el código que debe ser procesado por un intérprete de idiomas, por lo que estoy interesado en la posibilidad de compilar un script Python de geoprocesamiento en un archivo .EXE para trabajar con grandes datos.

¿Es esto posible? Si es así, ¿cuál es la mejor manera de compilar un script de Python (.py) que está importando los módulos arcgisscripting o arcpy?

Pasé unos minutos tratando de encontrar lo que quiero hacer y la búsqueda devolvió este artículo, entre otros: http://www.ehow.com/how_2091641_compile-python-code.html

El compilador parecía funcionar, pero al ejecutar el archivo .EXE resultante, dio un error críptico diciendo que algunos archivos no estaban disponibles.

El script de Python ejecuta lo que parece razonablemente bien desde la línea de comandos, pero me pregunto si podría ver una ligera mejora si pudiera compilar el archivo .py. Nuevamente, estoy trabajando con algunos grandes conjuntos de datos que están tardando más de 20 horas en procesarse (delinear las cuencas hidrográficas de los sitios de muestreo de calidad del agua de entrada). Tomaré todo lo que pueda para mejorar.

El guión corrió 10% más rápido fuera de ArcGIS desde la línea de comandos usando una prueba de conjunto de sitios de comparación de configurarlo como una herramienta de secuencia de comandos en una nueva caja de herramientas en ArcCatalog. He estado ejecutando el script desde la línea de comando sin ninguna instancia de ArcGIS abierta en una máquina dedicada.

Entonces, ¿es posible compilar scripts Python que importen el módulo arcgisscripting y que llamen herramientas ArcToolBox?

EDITAR

Gracias por el aporte, esto es útil para mí. La secuencia de comandos es en gran medida una forma de coordinar una serie de herramientas de ArcGIS y generar en los formatos / ubicaciones deseados / con la atribución adecuada. Creo que ya he recortado un poco de grasa escribiendo en una carpeta temporal en lugar de una geodatabase personal temporal para algunos archivos raster intermedios para que puedan almacenarse en el formato ESRI GRID frente al formato IMG. Sin embargo, revisaré las sugerencias de perfil.

Hay algunos en mi oficina que cuestionan a Python diciendo "que el código compilado es mucho más rápido que el código que se ejecuta a través de un intérprete" principalmente en comparación con, digamos, un programa compilado de Visual Basic o VB.NET, pero ese es un buen punto que las herramientas van a tomar tiempo de cualquier manera. Y, parece que con las máquinas informáticas actuales, el código interpretado puede no ser mucho más lento que el código compilado para garantizar un esfuerzo adicional.

EDITAR : actualización sobre la optimización del programa con formatos ráster.

Quería dar seguimiento a mi "optimización" de este programa de Python, y pude ahorrar 2 horas de tiempo de procesamiento escribiendo rásteres provisionales en formato GRID en lugar de en una geodatabase personal. No solo eso, hubo una reducción SIGNIFICATIVA en el consumo de espacio en disco del tamaño de datos. La ejecución original que escribí todos los rásteres (y solo eran entidades de puntos convertidas en rásteres, y luego rásteres de cuenca) resultó en 37.1 GB de datos solo para esos archivos. Escribir las últimas dos salidas de datos en una carpeta en formato GRID se redujo a 667 MB de datos.

Sería curioso ver cómo un archivo GDB manejaría estos datos, aunque principalmente en forma del tamaño de los datos. Pero, reducir mi tiempo de procesamiento de 9.5 horas a 7.5 horas ciertamente es suficiente para abogar por tratar con rásteres fuera de las geodatabases en el formato GRID.


El blog de ArcGIS Server de esta mañana es muy oportuno. Sterling @ esri hace un buen trabajo al describir por qué y cuándo [aquí.] [1] [1]: blogs.esri.com/Dev/blogs/arcgisserver/archive/2011/04/12/…
Brad Nesom

Respuestas:


15

Primera pregunta: ¿cuánto de esto estás haciendo en Python? ¿Está llamando a las herramientas de geoprocesamiento o está haciendo una cantidad significativa de análisis numérico en Python? Si es lo primero, es probable que los cuellos de botella vivan en las herramientas y el uso de código nativo en su secuencia de comandos no le comprará tanto como otras soluciones ingeniosas. Si es lo último, es posible que desee encontrar lo que es lento y hacerlo más rápido con mejores algoritmos, o posiblemente numpy, o alguna otra opción como se describe a continuación.

py2exe en realidad no compila su código a x86 / x64 nativo, solo proporciona un ejecutable que incorpora su script como bytecode y proporciona una forma principalmente portátil de distribuirlo a los usuarios sin Python en sus sistemas. Falló al intentar agrupar arcgisscripting, por lo que no funcionó. En realidad, hacer que py2exe funcione todavía no hará nada en cuanto al rendimiento.

Le recomiendo encarecidamente que primero use un generador de perfiles para identificar los bits lentos y optimizar desde allí. Hay un muy buen conjunto integrado en Python , use cProfile a largo plazo para encontrar lugares potenciales para hacerlo más rápido. Desde allí, puede optimizar las secciones en C personalizado o, posiblemente, experimentar con pequeñas porciones como módulos .pyx de Cython .

Puede buscar en Cython para posiblemente construir todo el script de Python como un módulo de extensión de código nativo, pero Psyco también puede darle un aumento de rendimiento con una barrera de entrada más baja.


4

¿Cuánto tiempo lleva la delineación de cuencas si se ejecuta desde las herramientas estándar en ArcToolbox en comparación con la versión del script? Si los tiempos son similares, sospecho que no habrá mejoría. Es posible que desee considerar ejecutar procesos largos en segundo plano fuera de ArcMap.


Aclaré mi pregunta original, y espero obtener una respuesta afirmativa de sí / no si es posible compilar dicho código, ya que esta respuesta no responde a mi pregunta.
turkishgold

2
@turkish Puede que no responda su pregunta directamente, pero es una excelente sugerencia. Lo más probable es que su proceso pase todo su tiempo en la delineación, por lo que ninguna cantidad de ajustes en el código ayudará de manera apreciable. Sin embargo, reconsiderar el algoritmo podría marcar una gran diferencia. Entonces, una de las primeras cosas que desea hacer es perfilar la ejecución actual para ver si está perdiendo el tiempo con este enfoque de compilación.
whuber

1
Estoy de acuerdo con @Dan y @whuber. Creo que hacer un análisis más profundo (es decir, evaluación comparativa y creación de perfiles) arrojará una visión mucho mejor para las mejoras de rendimiento que solo un enfoque de compilación de fuerza bruta.
Jason Scheirer

4

No use una geodatabase personal sin una buena razón. Según nuestra experiencia, son mucho más lentos que todas las demás formas de almacenamiento de datos de Esri ( ref ). Aunque he leído un informe aquí en GIS.se que vio más rápido personal que el archivo gdb.

Cuando el flujo de trabajo consta de muchas iteraciones pequeñas, la llamada para crear el geoprocesador y retirar una licencia suele ser la parte más costosa del uso de Python. Por lo tanto, hacer todo lo que pueda delante o detrás gp = ...(o import arcpyen v10) es una técnica que uso mucho.

Con respecto a la compilación, esta cita lo dice mejor:

Vale la pena señalar que mientras se ejecuta un script compilado [python] tiene un tiempo de inicio más rápido (ya que no necesita ser compilado), no se ejecuta más rápido.

Mark Cederholm tiene una presentación sobre el uso de ArcObjects en Python con algunas estadísticas sobre las operaciones de shapecopy (diapositiva # 4). Python no funciona muy bien, se ejecuta al 32% de lo que se puede lograr con C ++ (VBA fue del 92%, VB & C # al 48%). No corras y grites demasiado rápido, muchas de las herramientas de geoprocesamiento son scripts de Python de todos modos (busca '* .py' en c: \ program files \ arcgis \).

Como muchos han dicho en otros lugares, con python el tiempo dedicado a tratar de optimizar el rendimiento compilando o escribiendo una función central de C o C ++ a menudo eclipsa cualquier ganancia de rendimiento real (posiblemente) realizada en tiempo de ejecución. Muchos dicen que el principal beneficio de Python es optimizar y mejorar el tiempo del desarrollador ; La atención humana es mucho más valiosa y costosa que el tiempo de procesamiento de la máquina.


1
Sí en todos los aspectos. Para mi dinero, el uso óptimo del tiempo del desarrollador es crear un prototipo * en Python, punto de referencia, desplegable a C / C ++ para optimizar los cuellos de botella. * Digo prototipo, pero sé que el 95% de las veces ese 'prototipo' llegará a producción.
Jason Scheirer

Grandes comentarios y gracias por los enlaces en ArcObjects en Python. Creo que escribir en un GDB tiene beneficios desde una perspectiva de gestión de datos frente a shapefile (restricciones de la tabla de atributos en shapefiles frente a clases de entidad, representación de geometría, prácticas generales de gestión de datos, etc.), así como cosas que puede hacer de manera mucho más fácil y limpia. un entorno de acceso frente a tratar con archivos DBF. Entonces, básicamente una relación costo-beneficio con lo que está haciendo y lo que tendrá que hacer con los datos de salida. El término medio de rásteres fuera de GDB y todo lo demás en GDB parece estar funcionando.
turkishgold

1

No puede compilar código de Python en código de máquina. Cuando se ejecuta por primera vez, se compila en 'bytecode', un lenguaje intermedio (que crea archivos pyc)

py2exe envuelve los archivos dll requeridos por el intérprete y cualquier archivo python / externo requerido en un ejecutable. No está compilado: el tiempo de ejecución no debería ser muy diferente.

Es posible hacer que el código Python se ejecute muy rápido, usando una combinación de diferentes técnicas.

Lo primero que debe hacer es perfilar su código para encontrar los cuellos de botella. Una vez encontrado, generalmente uso este proceso:

  • Elimine los bucles 'for' utilizando matrices numpy o la función map (). Esto básicamente empuja el bucle hacia C.
  • Investigue mejores implementaciones del algoritmo (este tipo de coincide con el anterior). Cosas como reducir el número de operaciones de E / S, asegurando el acceso / almacenamiento de datos en bloques contiguos.
  • Los 'trucos' del intérprete, como evitar búsquedas costosas dentro de los bucles, evitar los bloques 'if' dentro de los bucles (use 'try' en su lugar)
  • Perfílelo de nuevo
  • Si todavía es demasiado lento, mire cómo empujar partes críticas en C usando Cython (o escribiendo directamente en C, creando un dll y usando ctypes para llamarlo)
  • Perfil de nuevo
  • Si aún es demasiado lento, observe la computación paralela o GPU (biblioteca de multiprocesamiento, pyCUDA, ParallelPython, etc.)

0

Si importa una secuencia de comandos de Python desde otra ubicación, genera un archivo .pyc. Entonces, una manera fácil de probar si la compilación hace la diferencia sería convertir su script en una función (por ejemplo, main ()). Si guarda esa secuencia de comandos, example.pycree otro archivo con las siguientes líneas:

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

Si ejecuta el tiempo desde el script y se ejecuta cuando se importa, tal vez pueda ver cuál es la diferencia. Sin embargo, esta es una forma de baja tecnología de hacerlo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.