Bien que cette question ait déjà été répondue, je pensais pouvoir donner un coup de pouce à mes deux cents.
AVERTISSEMENT : J'ai travaillé pour ESRI au sein de l'équipe de GeoDatabase pendant quelques années et j'étais responsable de la maintenance de diverses parties du code de GeoDatabase (versioning, curseurs, sessions d'édition, historique, classes de relations, etc.).
Je pense que la plus grande source de problèmes de performances avec le code ESRI n’est pas la compréhension des implications de l’utilisation d’objets différents, en particulier les "petits" détails des différentes abstractions de GeoDatabase! Alors très souvent, la conversation bascule sur le langage utilisé comme responsable des problèmes de performances. Dans certains cas, cela peut être. Mais pas tout le temps. Commençons par la discussion sur la langue et revenons en arrière.
1.- Le langage de programmation que vous choisissez n'a d'importance que lorsque vous faites quelque chose de compliqué, en boucle serrée. La plupart du temps, ce n'est pas le cas.
Le gros éléphant dans la pièce est qu’au cœur de tout le code ESRI, vous avez ArcObjects - et ArcObjects est écrit en C ++ en utilisant COM . La communication avec ce code a un coût. Cela est vrai pour C #, VB.NET, Python ou tout ce que vous utilisez.
Vous payez un prix lors de l'initialisation de ce code. Cela peut représenter un coût négligeable si vous ne le faites qu'une fois.
Vous payez ensuite un prix pour chaque interaction ultérieure avec ArcObjects.
Personnellement, j’ai tendance à écrire du code pour mes clients en C #, car c’est facile et rapide. Cependant, chaque fois que je souhaite déplacer des données ou effectuer un traitement pour de grandes quantités de données déjà implémentées dans le géotraitement, je viens d'initialiser le sous-système de script et de transmettre mes paramètres. Pourquoi?
- Il est déjà mis en œuvre. Alors pourquoi réinventer la roue?
- Cela peut être plus rapide . "Plus rapide que de l'écrire en C #?" Oui! Si je mets en œuvre, par exemple, le chargement de données manuellement, cela signifie que je paie le prix de la commutation de contexte .NET dans une boucle serrée. Chaque GetValue, Insert, ShapeCopy a un coût. Si je passe un seul appel dans GP, l'ensemble du processus de chargement de données aura lieu lors de la mise en œuvre réelle de GP - en C ++ dans l'environnement COM. Je ne paie pas le prix du changement de contexte car il n'y en a pas - et par conséquent, il est plus rapide.
Ah oui, alors la solution consiste à utiliser de nombreuses fonctions de géotraitement. En fait, il faut faire attention.
2. GP est une boîte noire qui copie des données (potentiellement inutilement) autour
C'est une épée à double tranchant. C'est une boîte noire qui fait un peu de magie en interne et crache des résultats - mais ces résultats sont très souvent dupliqués. 100 000 lignes peuvent facilement être converties en 1 000 000 lignes sur disque après avoir exécuté vos données via 9 fonctions différentes. Utiliser uniquement les fonctions GP, c'est comme créer un modèle GP linéaire, et bien ...
3. Le chaînage d'un trop grand nombre de fonctions de gestion de stratégie pour des ensembles de données volumineux est extrêmement inefficace. Un modèle de stratégie de groupe équivaut (potentiellement) à exécuter une requête de manière vraiment très stupide
Maintenant, ne vous méprenez pas. J'aime les modèles GP - cela me évite d'écrire du code tout le temps. Mais je suis également conscient que ce n'est pas le moyen le plus efficace de traiter de grands ensembles de données.
Avez-vous tous entendu parler d'un planificateur de requêtes ? Son travail consiste à examiner l'instruction SQL que vous souhaitez exécuter, à générer un plan d'exécution sous la forme d'un graphe dirigé ressemblant beaucoup à un modèle de stratégie de groupe , à examiner les statistiques stockées dans la base de données et à choisir le plus ordre optimal pour les exécuter . GP les exécute simplement dans l'ordre où vous mettez les choses, car il n'a pas de statistiques pour faire quoi que ce soit plus intelligemment - vous êtes le planificateur de requêtes . Et devine quoi? L'ordre dans lequel vous exécutez les choses dépend beaucoup de votre jeu de données. L’ordre dans lequel vous exécutez les choses peut faire la différence entre les jours et les secondes et c’est à vous de décider.
"Génial", dites-vous, je ne vais pas écrire le scénario moi-même et faire attention à la façon dont j'écris. Mais comprenez-vous les abstractions de GeoDatabase?
4. Ne pas comprendre les abstractions de GeoDatabase peuvent facilement vous mordre
Au lieu de signaler tout ce qui peut éventuellement vous poser un problème, laissez-moi simplement vous signaler quelques erreurs courantes que je vois tout le temps et quelques recommandations.
- Comprendre la différence entre les curseurs Vrai / Faux pour le recyclage . Ce minuscule indicateur défini sur true peut accélérer les ordres de grandeur d'exécution.
- Placez votre table dans LoadOnlyMode pour les chargements de données. Pourquoi mettre à jour l'index à chaque insertion?
- Comprenez que même si IWorkspaceEdit :: StartEditing est identique dans tous les espaces de travail, il s’agit de créatures très différentes sur chaque source de données. Sur une GDB d’entreprise, vous pouvez avoir un contrôle de version ou un support pour les transactions. Sur les fichiers de formes, il devra être mis en œuvre de manière très différente. Comment mettriez-vous en oeuvre Undo / Redo? Avez-vous même besoin de l'activer (oui, cela peut faire une différence dans l'utilisation de la mémoire).
- Différence entre les opérations de traitement par lots ou les opérations sur une seule ligne. Cas concret GetRow vs GetRows - c'est la différence entre effectuer une requête pour obtenir une ligne ou effectuer une requête pour extraire plusieurs lignes. Une boucle étroite avec un appel à GetRow signifie une performance épouvantable et c'est le premier coupable des problèmes de performance
- Utilisez UpdateSearchedRows
- Comprendre la différence entre CreateRow et CreateRowBuffer . Grande différence dans le temps d'exécution des insertions.
- Comprenez qu'IRow :: Store et IFeature :: Store déclenchent des opérations polymorphes extrêmement lourdes .C'est probablement la raison n ° 2 coupable d'une performance très lente. Il ne s'agit pas simplement d'enregistrer la ligne. Il s'agit de la méthode permettant de vérifier que votre réseau géométrique est correct, que l'éditeur d'ArcMap est averti qu'une ligne a été modifiée, ainsi que toutes les classes de relations ayant un lien avec cette ligne. assurez-vous que la cardinalité est valide, etc. Vous ne devriez pas insérer de nouvelles lignes avec cela, vous devriez utiliser un InsertCursor !
- Voulez-vous (besoin) de faire ces insertions dans une EditSession? Cela fait une énorme différence si vous faites ou non. Certaines opérations le requièrent (et ralentissent le processus), mais lorsque vous n'en avez pas besoin, ignorez les fonctions annuler / rétablir.
- Les curseurs sont des ressources coûteuses. Une fois que vous en avez un, vous avez la garantie d'avoir la cohérence et l'isolement et cela a un coût.
- Cachez d'autres ressources telles que les connexions à la base de données (ne créez pas et ne détruisez pas votre référence Workspace) et les poignées de table (chaque fois que vous ouvrez ou fermez un - plusieurs tables de métadonnées doivent être lues).
- Placer FeatureClasses à l'intérieur ou à l'extérieur d'un FeatureDataset fait une énorme différence en termes de performances. Ce n'est pas conçu comme une caractéristique organisationnelle!
5. Enfin et surtout ...
Comprendre la différence entre opérations liées aux E / S et aux unités centrales
Honnêtement, j'ai envisagé de développer davantage chacun de ces éléments et peut-être de faire une série d'entrées de blog couvrant chacun de ces sujets, mais la liste d'arriéré de mon agenda ne m'a que giflé et a commencé à crier après moi.
Mes deux centimes.