Aunque esta pregunta ya fue respondida, pensé que podía sonar y dar mis dos centavos.
DESCARGO DE RESPONSABILIDAD : Trabajé para ESRI en el equipo de GeoDatabase durante algunos años y estaba a cargo de mantener varias partes del código de GeoDatabase (versiones, cursores, sesiones de edición, historia, clases de relación, etc.).
¡Creo que la mayor fuente de problemas de rendimiento con el código ESRI no es comprender las implicaciones del uso de diferentes objetos, en particular, los "pequeños" detalles de las diversas abstracciones de GeoDatabase! Muy a menudo, la conversación cambia al idioma que se utiliza como culpable de los problemas de rendimiento. En algunos casos puede ser. Pero no todo el tiempo. Comencemos con la discusión del idioma y trabajemos de regreso.
1.- El lenguaje de programación que eliges solo importa cuando estás haciendo algo complicado, en un ciclo cerrado. La mayoría de las veces, este no es el caso.
El gran elefante en la sala es que en el núcleo de todo el código ESRI, tienes ArcObjects, y ArcObjects está escrito en C ++ usando COM . Hay un costo por comunicarse con este código. Esto es cierto para C #, VB.NET, python o cualquier otra cosa que esté utilizando.
Usted paga un precio al inicializar ese código. Eso puede ser un costo insignificante si lo hace solo una vez.
Luego paga un precio por cada vez que interactúa con ArcObjects.
Personalmente, tiendo a escribir código para mis clientes en C #, porque es lo suficientemente 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án implementados en Geoprocesamiento , solo inicializo el subsistema de secuencias de comandos 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, digamos, carga de datos manualmente, significa que pago el precio de la conmutación de contexto .NET en un ciclo cerrado. Cada GetValue, Insert, ShapeCopy tiene un costo. Si hago una 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 por el cambio de contexto porque no hay ninguno, y por lo tanto es más rápido.
Ah, sí, entonces la solución es usar muchas funciones de geoprocesamiento. En realidad, tienes que tener cuidado.
2. GP es un cuadro negro que copia datos (potencialmente innecesarios) alrededor
Es una espada de doble filo. Es una caja negra que hace algo de magia internamente y escupe resultados, pero esos resultados a menudo se duplican. 100,000 filas se pueden convertir fácilmente en 1,000,000 filas en el disco después de ejecutar sus datos a través de 9 funciones diferentes. Usar solo funciones GP es como crear un modelo GP lineal, y bueno ...
3. Encadenar demasiadas funciones GP para grandes conjuntos de datos es altamente ineficiente. Un modelo GP es (potencialmente) equivalente a ejecutar una consulta de una manera realmente muy tonta
Ahora no me malinterpretes. Me encantan los modelos GP: me evita 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 de un planificador de consultas ? Su trabajo es mirar la declaración SQL que desea ejecutar, generar un plan de ejecución en forma de un gráfico dirigido que se parezca mucho a un modelo GP , mirar las estadísticas almacenadas en la base de datos y elegir la mayoría orden óptimo para ejecutarlos . GP solo las ejecuta en el orden en que las coloca porque no tiene estadísticas para hacer nada de manera más inteligente: usted es el planificador de consultas . ¿Y adivina qué? El orden en el que ejecuta las cosas depende mucho de su conjunto de datos. El orden en el que ejecuta las cosas puede marcar la diferencia entre días y segundos y eso depende de usted decidir.
"Genial", dices, no escribiré las cosas yo mismo y seré cuidadoso sobre cómo escribo cosas. ¿Pero entiendes las abstracciones de GeoDatabase?
4. No entender las abstracciones de GeoDatabase puede morderte fácilmente
En lugar de señalar cada cosa que posiblemente pueda darte un problema, permíteme señalar algunos errores comunes que veo todo el tiempo y algunas recomendaciones.
- Comprender la diferencia entre verdadero / falso para reciclar cursores . Esta pequeña bandera configurada como verdadera puede hacer que los órdenes de magnitud de tiempo de ejecución sean más rápidos.
- Ponga su tabla en LoadOnlyMode para cargas de datos. ¿Por qué actualizar el índice en cada inserción?
- Comprenda que aunque IWorkspaceEdit :: StartEditing se ve igual en todos los espacios de trabajo, son bestias muy diferentes en cada fuente de datos. En un Enterprise GDB, puede tener versiones o soporte para transacciones. En los archivos de forma, tendrá que implementarse de una manera muy diferente. ¿Cómo implementaría Deshacer / Rehacer? ¿Incluso necesita habilitarlo (sí, puede marcar la diferencia en el uso de la memoria).
- La diferencia entre operaciones por lotes u operaciones de una sola fila. Caso en cuestión GetRow vs GetRows : esta es la diferencia entre hacer una consulta para obtener una fila o hacer una consulta para obtener varias filas. Un ciclo cerrado con una llamada a GetRow significa un rendimiento horrible y es el culpable # 1 de problemas de rendimiento
- Utilice UpdateSearchedRows
- Comprenda la diferencia entre CreateRow y CreateRowBuffer . Gran diferencia en el tiempo de ejecución del inserto.
- Comprenda que IRow :: Store y IFeature :: Store activan operaciones polimórficas súper pesadas . Esta es probablemente la razón # 2 culpable de un rendimiento realmente lento. No solo guarda la fila, este es el método que asegura que su red geométrica esté bien, que ArcMap Editor reciba 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 hacer asegúrese de que la cardinalidad sea válida, etc. ¡No debería insertar nuevas filas con esto, debería usar un cursor de inserción !
- ¿Desea (necesita) hacer esas inserciones en una sesión de edición? Hace una gran diferencia si lo haces o no. Algunas operaciones lo requieren (y hacen las cosas más lentas), pero cuando no lo necesite, omita las funciones de deshacer / rehacer.
- Los cursores son recursos caros. Una vez que tenga un identificador para uno, se le garantiza que tendrá Consistencia y Aislamiento y eso tiene un costo.
- Guarde en caché otros recursos como conexiones de base de datos (no cree y destruya su referencia de espacio de trabajo) y controladores de tabla (cada vez que abra o cierre uno, se deben leer varias tablas de metadatos).
- Poner FeatureClasses dentro o fuera de un FeatureDataset hace una gran diferencia en el rendimiento. Se no se entiende como una característica de la organización!
5. Y por último y no menos importante ...
Comprender la diferencia entre las operaciones vinculadas de E / S y CPU
Honestamente, pensé en expandirme más en cada uno de esos elementos y tal vez hacer una serie de entradas de blog que cubrieran cada uno de esos temas, pero la lista de trabajo pendiente de mi calendario me abofeteó y comenzó a gritarme.
Mis dos centavos.