39 votos

Rendimiento de ArcGISScripting y grandes conjuntos de datos espaciales

Actualmente estoy escribiendo un script en python utilizando el módulo arcgisscripting para procesar un conjunto de datos razonablemente grande (~10.000 registros en total) normalizado en un pequeño número de tablas, 8 en total. El proceso consiste en crear una característica basada en tuplas de coordenadas (x,y) y crear un gráfico (nodos y líneas) utilizando las relaciones de las otras 7 tablas como guía. El resultado final es una geodatabase personal (pgdb/fgdb) con conjuntos de datos espaciales de nodos y aristas que representan visualmente las relaciones.

Mi intento inicial fue utilizar las consultas de las nuevas tablas de la geodatabase y los conjuntos de registros de SearchCursor para rellenar las tablas de enlace (InsertCursor) para las relaciones de muchos a muchos que se producen. Esto funcionó muy bien, excepto por el tiempo de procesamiento de 15-20 minutos.

Utilizando el módulo cProfiler en Python, se ha visto que el "golpeo" de una geodatabase personal al realizar las consultas de búsqueda para poblar las tablas de enlaces con solicitudes de cursores (cursores de búsqueda e inserción) era la causa del pésimo rendimiento.

Con un poco de refactorización he conseguido que el tiempo de procesamiento sea inferior a 2,5 minutos. La contrapartida fue la construcción parcial del esquema de la geodatabase en código y la limitación de las peticiones de cursores de arcgisscripting a InsertCursors una vez cotejadas todas las relaciones.

Mi pregunta es de rendimiento;

  • ¿Qué técnicas se han utilizado para mantener tiempos de cálculo razonables cuando se trabaja con grandes conjuntos de datos?

  • ¿Hay algún método recomendado por el ESRI que haya pasado por alto en mi búsqueda de optimización?

    Comprendo la sobrecarga en la que se incurre al crear un cursor de arcgisscripting, especialmente si se trata de una base de datos geográfica personal, aunque después de una larga búsqueda de respuestas relacionadas con el rendimiento en este sitio y en Google, tengo la impresión de que el rendimiento no está a la vanguardia de los esfuerzos de la gente.

  • Como usuario de los productos de ESRI, ¿espera y aprueba estos retrasos en el rendimiento?


ACTUALIZACIÓN

Después de algunos trabajos con este producto he acumulado una lista de técnicas de optimización que han llevado un proceso de conversión de información espacial de un formato propio a una geodatabase. Esto se ha desarrollado para la geodatabase personal y de archivo. Datos de interés:

  1. Lee tus datos y racionalízalos en la memoria. Esto reducirá su tiempo a la mitad.

  2. Crear clases y tablas de características en la memoria. Utilice la clave del conjunto de datos de características 'in_memory' para utilizar su memoria como disco ram, realice sus funciones allí y luego escriba en el disco

  3. Para escribir en el disco utilice CopyFeatureclass para las clases de características, y CopyRow para las tablas.

Estas 3 cosas hicieron que un script que convertía más de 100.000 características en una base de datos geográfica pasara de 30 minutos a 30-40 segundos, incluyendo las clases de relación. No son para ser utilizados a la ligera, la mayoría de los métodos anteriores utilizan una gran cantidad de memoria, lo que podría causar problemas si usted no está prestando atención.

56voto

FlySwat Puntos 61945

Aunque esta pregunta ya ha sido respondida, he pensado que podría intervenir y dar mi opinión.

DESCARGO DE RESPONSABILIDAD : Trabajé para ESRI en el equipo de GeoDatabase durante algunos años y estuve a cargo del mantenimiento de varias partes del código de GeoDatabase (Versioning, Cursors, EditSessions, History, Relationship Classes, etc etc).

Creo que la mayor fuente de problemas de rendimiento con el código de ESRI es no entender las implicaciones del uso de diferentes objetos, en particular, los "pequeños" detalles de las diversas abstracciones de la base de datos geográfica. Así que muy a menudo, la conversación cambia al lenguaje que se utiliza como culpable de los problemas de rendimiento. En algunos casos puede serlo. Pero no siempre. Empecemos con la discusión sobre el lenguaje y vayamos hacia atrás.

1.- El lenguaje de programación que elijas sólo importa cuando estés haciendo algo complicado, en un bucle cerrado. La mayoría de las veces, este no es el caso.

El gran elefante en la habitación es que en el núcleo de todo el código de ESRI, tienes ArcObjects - y ArcObjects está escrito en C++ utilizando COM . La comunicación con este código tiene un coste. Esto es cierto para C#, VB.NET, python, o cualquier otra cosa que esté utilizando.

Se paga un precio en la inicialización de ese código. Puede ser un coste insignificante si lo haces una sola vez.

A continuación, se paga un precio por cada vez que se interactúa con ArcObjects.

Personalmente, tiendo a escribir código para mis clientes en C#, porque es bastante fácil y rápido. Sin embargo, cada vez que quiero mover datos o hacer algún procesamiento para grandes cantidades de datos que ya está implementado en Geoprocessing Simplemente inicializo el subsistema de scripting y paso mis parámetros. ¿Por qué?

  • Ya está implementado. Entonces, ¿por qué reinventar la rueda?
  • En realidad puede ser más rápido . "¿Más rápido que escribirlo en C#?" Sí. Si implemento, por ejemplo, la carga de datos manualmente, significa que pago el precio del cambio de contexto de .NET en un bucle cerrado. Cada GetValue, Insert, ShapeCopy tiene un coste. Si hago la única llamada en GP, todo el proceso de carga de datos ocurrirá en la implementación real de GP - en C++ dentro del entorno COM. No pago el precio del cambio de contexto porque no hay ninguno - y por lo tanto es más rápido.

Ah, sí, entonces la solución es utilizar muchas funciones de geoprocesamiento. En realidad, hay que tener cuidado.

2. La GP es una caja negra que copia datos (potencialmente innecesarios) por

Es un arma de doble filo. Es una caja negra que hace algo de magia internamente y escupe resultados, pero esos resultados se duplican muy a menudo. 100.000 filas pueden convertirse fácilmente en 1.000.000 de filas en el disco después de haber pasado los datos por 9 funciones diferentes. Usar sólo funciones de GP es como crear un modelo lineal de GP, y bueno...

3. Encadenar demasiadas funciones GP para grandes conjuntos de datos es muy ineficiente. Un modelo de GP es (potencialmente) equivalente a ejecutar una consulta de una manera realmente muy tonta

No me malinterpretes. Me encantan los Modelos GP - me ahorran escribir código todo el tiempo. Pero también soy consciente de que no es la forma más eficiente de procesar grandes conjuntos de datos.

¿Has oído hablar alguna vez de un Planificador de consultas ? Su trabajo es mirar la sentencia SQL que quieres ejecutar, generar un plan de ejecución en forma de grafo dirigido que se parece mucho a un Modelo GP , mira las estadísticas almacenadas en la db, y elige el el orden más óptimo para ejecutarlas . GP se limita a ejecutarlas en el orden en que las pones porque no tiene estadísticas para hacer algo más inteligente - usted es el planificador de la consulta . ¿Y adivina qué? El orden en el que se ejecutan las cosas depende en gran medida del conjunto de datos. El orden en el que se ejecutan las cosas puede marcar la diferencia entre días y segundos, y eso lo decides tú.

"Estupendo", dirás, no voy a guionizar las cosas yo mismo y voy a tener cuidado con cómo escribo las cosas. Pero, ¿entiendes las abstracciones de las bases de datos geográficas?

4.No entender las abstracciones de las bases de datos geográficas puede ser un problema.

En lugar de señalar cada una de las cosas que pueden suponer un problema, permítanme señalar algunos errores comunes que veo todo el tiempo y algunas recomendaciones.

  • Comprender la diferencia entre Verdadero/Falso para los cursores de reciclaje . Esta pequeña bandera puesta a true puede hacer que el tiempo de ejecución sea órdenes de magnitud más rápido.
  • Ponga su mesa en LoadOnlyMode para la carga de datos. ¿Por qué actualizar el índice en cada inserción?
  • Comprenda que aunque IWorkspaceEdit::StartEditing tiene el mismo aspecto en todos los espacios de trabajo, son bestias muy diferentes en cada fuente de datos. En un GDB de empresa, es posible que tenga un sistema de versiones o soporte para transacciones. En los shapefiles, tendrá que ser implementado de una manera muy diferente. ¿Cómo se implementa la función de deshacer/rehacer? ¿Es necesario activarlo (sí, puede suponer una diferencia en el uso de la memoria)?
  • La diferencia entre las operaciones por lotes, o las operaciones de una sola fila. Un ejemplo GetRow vs GetRows - esta es la diferencia entre hacer una consulta para obtener una fila o hacer una consulta para obtener varias filas. Un bucle cerrado con una llamada a GetRow significa un rendimiento horrible y es el culpable nº 1 de los problemas de rendimiento
  • Utilice UpdateSearchedRows
  • Comprender la diferencia entre CreateRow y CreateRowBuffer . Enorme diferencia en el tiempo de ejecución de la inserción.
  • Entienda que IRow::Store y IFeature::Store desencadena un proceso superpesado polimórfico operaciones. Esta es probablemente la razón #2 culpable del rendimiento realmente lento. No sólo guarda la fila, este es el método que se asegura de que su red geométrica está bien, que el editor de ArcMap recibe una notificación de que una fila ha cambiado, que notifica a todas las clases de relación que tienen algo que ver con esta fila validar para asegurarse de que la cardinalidad es válida, etc. Usted no debe ser la inserción de nuevas filas con esto, usted debe ser el uso de un InsertCursor ¡!
  • ¿Quiere (necesita) hacer esas inserciones en una EditSession? Hace un enorme diferencia si lo haces o no. Algunas operaciones lo requieren (y hacen las cosas más lentas), pero cuando no lo necesites, omite las funciones de deshacer/rehacer.
  • Los cursores son recursos caros. Una vez que se tiene el manejo de uno, se garantiza que se tendrá Coherencia y aislamiento y eso tiene un coste.
  • Almacene en caché otros recursos como las conexiones a la base de datos (no cree y destruya su referencia al espacio de trabajo) y los manejadores de las tablas (cada vez que abra o cierre una, es necesario leer varias tablas de metadatos).
  • Poner FeatureClasses dentro o fuera de un FeatureDataset hace una gran diferencia en el rendimiento. Es no se entiende como un elemento de organización.

5.Y por último y no menos importante...

Comprender la diferencia entre Operaciones ligadas a la E/S y a la CPU

Sinceramente, he pensado en extenderme más en cada uno de esos temas y quizás hacer una serie de entradas en el blog que cubran cada uno de esos temas, pero la lista de pendientes de mi calendario me abofeteó en la cara y empezó a gritarme.

Mis dos centavos.

5voto

Gareth Jenkins Puntos 1480

En general, para los cálculos de rendimiento, intento mantenerme alejado del uso de cualquier material relacionado con ESRI. Para su ejemplo, yo sugeriría hacer el proceso en pasos, el primer paso de la lectura de los datos en los objetos normales de python, haciendo los cálculos, y luego el paso final de la conversión al formato espacial ESRI final. Para ~10k registros, probablemente podría salirse con la suya almacenando todo en memoria para el procesamiento, lo que daría una ganancia de rendimiento definitiva.

1voto

Jonny Puntos 207

Dependiendo del hardware que tengas, también podrías considerar la opción que se muestra en el ejemplo de ESRI Geocoder; te da un marco para dividir un gran conjunto de datos y ejecutar múltiples instancias de python para darte casi un enfoque multihilo. He visto que el rendimiento de la geocodificación ha pasado de 180.000 por hora en una sola instancia de Python a más de un millón gracias a la ejecución de 8 procesos paralelos en mi máquina.

He visto que alejarme todo lo que puedo y mantener el trabajo de datos en la base de datos, y el trabajo funcional en mis tablas y sólo utilizar lo que es SIG explícito en el ámbito de ESRI da importantes aumentos de rendimiento.

0voto

yves Baumes Puntos 243

Puede que estos otros posts del foro te resulten interesantes, ya que están en el contexto de la optimización pero para datos rasterizados y en general:

¿Compilación de scripts de Python que utilizan las herramientas de geoprocesamiento de ArcGIS?

¿Tiempo de procesamiento utilizando las herramientas de la caja de herramientas de ArcGIS Hydrology en un script independiente de Python frente a ArcCatalog?

el ajuste gp.scratchworkspace hizo una gran diferencia para mí en un código de python que escribí para hacer delineaciones de cuencas.

¿Podría publicar algunos ejemplos de código que demuestren los números 1 y 2 en su UPDATE a su pregunta original? Me interesaría ver la mecánica de eso (aunque asumo que estás tratando con datos de clases de características solamente)

gracias, Tom

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X