Anche se a questa domanda era già stata data una risposta, ho pensato di poter suonare in due modi.
DISCLAIMER : Ho lavorato per ESRI nel team di GeoDatabase per alcuni anni e mi sono occupato di mantenere varie parti del codice GeoDatabase (Versioning, Cursors, EditSessions, History, Relationship Classes, etc etc).
Penso che la più grande fonte di problemi di prestazioni con il codice ESRI non sia comprendere le implicazioni dell'uso di oggetti diversi, in particolare i "piccoli" dettagli delle varie astrazioni di GeoDatabase! Molto spesso, la conversazione passa alla lingua utilizzata come colpevole dei problemi di performance. In alcuni casi può essere. Ma non sempre. Cominciamo con la discussione sulla lingua e torniamo indietro.
1.- Il linguaggio di programmazione che scegli è importante solo quando stai facendo qualcosa di complicato, in un circuito stretto. Il più delle volte, non è così.
Il grande elefante nella stanza è che al centro di tutto il codice ESRI, hai ArcObjects - e ArcObjects è scritto in C ++ usando COM . C'è un costo per comunicare con questo codice. Questo è vero per C #, VB.NET, Python o qualsiasi altra cosa tu stia usando.
Paghi un prezzo all'inizializzazione di quel codice. Potrebbe essere un costo trascurabile se lo fai solo una volta.
Quindi paghi un prezzo ogni volta che interagisci con ArcObjects.
Personalmente, tendo a scrivere codice per i miei clienti in C #, perché è abbastanza facile e veloce. Tuttavia, ogni volta che desidero spostare i dati o elaborarli per grandi quantità di dati già implementati in Geoprocessing, ho appena inizializzato il sottosistema di scripting e passato i miei parametri. Perché?
- È già implementato. Quindi perché reinventare la ruota?
- In realtà potrebbe essere più veloce . "Più veloce di scriverlo in C #?" Sì! Se implemento, diciamo, il caricamento manuale dei dati, significa che pago il prezzo del cambio di contesto .NET in un ciclo stretto. Ogni GetValue, Insert, ShapeCopy ha un costo. Se faccio una chiamata in GP, l'intero processo di caricamento dei dati avverrà nell'attuazione effettiva di GP - in C ++ all'interno dell'ambiente COM. Non pago il prezzo per il cambio di contesto perché non ce ne sono - e quindi è più veloce.
Ah sì, quindi la soluzione se usare molte funzioni di geoprocessing. In realtà, devi stare attento.
2. GP è una scatola nera che copia i dati (potenzialmente inutilmente) in giro
È un'arma a doppio taglio. È una scatola nera che fa un po 'di magia internamente e sputa risultati - ma questi risultati sono spesso duplicati. 100.000 righe possono essere facilmente convertite in 1.000.000 di righe sul disco dopo aver eseguito i dati attraverso 9 diverse funzioni. Usare solo le funzioni GP è come creare un modello GP lineare, e bene ...
3. Concatenare troppe funzioni GP per set di dati di grandi dimensioni è altamente inefficiente. Un modello GP è (potenzialmente) equivalente all'esecuzione di una query in un modo davvero molto stupido
Ora non fraintendermi. Adoro i modelli GP: mi salva dal scrivere codice tutto il tempo. Ma sono anche consapevole che non è il modo più efficiente di elaborare set di dati di grandi dimensioni.
Hai mai sentito parlare di un Query Planner ? Il suo compito è guardare l'istruzione SQL che si desidera eseguire, generare un piano di esecuzione sotto forma di un grafico diretto che assomigli molto a un modello GP , guardare le statistiche memorizzate nel db e scegliere il più ordine ottimale per eseguirli . GP li esegue semplicemente nell'ordine in cui metti le cose perché non ha statistiche per fare qualcosa di più intelligente - sei il pianificatore di query . E indovina cosa? L'ordine in cui esegui le cose dipende molto dal tuo set di dati. L'ordine in cui esegui le cose può fare la differenza tra giorni e secondi e spetta a te decidere.
"Fantastico" dici, non scriverò le cose da solo e starò attento a come scrivo le cose. Ma capisci le astrazioni di GeoDatabase?
4. Non capire le astrazioni di GeoDatabase può facilmente morderti
Invece di sottolineare ogni singola cosa che può darti un problema, lasciami solo segnalare alcuni errori comuni che vedo continuamente e alcuni consigli.
- Comprensione della differenza tra i cursori Vero / Falso per il riciclaggio . Questa piccola bandiera impostata su true può velocizzare gli ordini di runtime di grandezza.
- Inserisci la tabella in LoadOnlyMode per i carichi di dati. Perché aggiornare l'indice su ogni inserto?
- Tieni presente che anche se IWorkspaceEdit :: StartEditing sembra lo stesso in tutte le aree di lavoro, sono bestie molto diverse su ogni origine dati. Su un GDB aziendale, potresti avere il controllo delle versioni o il supporto per le transazioni. Su shapefile, dovrà essere implementato in un modo molto diverso. Come implementeresti Annulla / Ripeti? Hai anche bisogno di abilitarlo (sì, può fare la differenza nell'utilizzo della memoria).
- La differenza tra operazioni batch o operazioni a riga singola. Caso in questione GetRow vs GetRows : questa è la differenza tra l'esecuzione di una query per ottenere una riga o l'esecuzione di una query per il recupero di più righe. Un circuito chiuso con una chiamata a GetRow significa prestazioni orribili ed è il colpevole numero 1 dei problemi di prestazioni
- Usa UpdateSearchedRows
- Comprendi la differenza tra CreateRow e CreateRowBuffer . Enorme differenza nel runtime dell'inserto.
- Comprendi che IRow :: Store e IFeature :: Store innesca operazioni polimorfiche super pesanti . Questo è probabilmente il motivo numero 2 colpevole di prestazioni davvero lente. Non solo salva la riga, questo è il metodo che assicura che la tua rete geometrica sia OK, che l'Editor ArcMap venga avvisato che una riga è cambiata, che notifica tutte le classi di relazione che hanno qualcosa a che fare con questa riga convalidate per rendere sicuro che la cardinalità sia valida, ecc. Non dovresti inserire nuove righe con questo, dovresti usare un InsertCursor !
- Vuoi (hai bisogno) di fare quegli inserti in una EditSession? Fa una grande differenza se lo fai o no. Alcune operazioni lo richiedono (e rendono le cose più lente), ma quando non ne hai bisogno, salta le funzionalità di annullamento / ripetizione.
- I cursori sono risorse costose. Una volta che hai una maniglia per uno, hai la garanzia che avrai Coerenza e Isolamento e che avrà un costo.
- Memorizza nella cache altre risorse come connessioni al database (non creare e distruggere il riferimento dello spazio di lavoro) e handle di tabella (ogni volta che ne apri o chiudi uno - devi leggere diverse tabelle di metadati).
- Inserire FeatureClasses all'interno o all'esterno di un FeatureDataset fa una differenza enorme nelle prestazioni. E ' non è inteso come una caratteristica organizzativa!
5.E ultimo e non meno importante ...
Comprendere la differenza tra operazioni di I / O associate e operazioni legate alla CPU
Onestamente ho pensato di espandermi di più su ciascuno di quegli elementi e forse di fare una serie di post di blog che trattano ognuno di quegli argomenti, ma l'elenco degli arretrati del mio calendario mi ha appena schiaffeggiato e ha iniziato a urlarmi.
I miei due centesimi.