Prestazioni di ArcGISScripting e grandi set di dati spaziali


38

Attualmente sto scrivendo uno script Python usando il modulo arcgisscripting per elaborare un set di dati ragionevolmente grande (~ 10.000 record in totale) normalizzato su un piccolo numero di tabelle, 8 in totale. Il processo consiste nella creazione di una funzione basata su tuple di coordinate (x, y) e sulla creazione di un grafico (nodi e linee) utilizzando le relazioni nelle altre 7 tabelle come guida. L'output finale è un geodatabase personale (pgdb / fgdb) con set di dati spaziali di nodi e bordi che rappresentano visivamente le relazioni.

Il mio tentativo iniziale era di utilizzare le query delle nuove tabelle di geodatabase e set di record SearchCursor per popolare le tabelle dei collegamenti (InsertCursor) per le relazioni molti-a-molti che si verificano. Questo ha funzionato molto bene, ad eccezione del tempo di elaborazione di 15-20 minuti.

Utilizzando il modulo cProfiler in Python, era evidente che il "blocco" di un geodatabase personale durante l'esecuzione delle query di ricerca per popolare le tabelle dei collegamenti con richieste di cursori (Cerca e Inserisci cursori) ha causato prestazioni spaventose.

Con un piccolo refactoring sono riuscito a ottenere un tempo di elaborazione inferiore a 2,5 minuti. Il compromesso è stato la costruzione parziale dello schema di geodatabase in codice e la limitazione delle richieste di cursori di arcgisscript a InsertCursors una volta raccolte tutte le relazioni.

La mia domanda è di prestazioni;

  • Quali tecniche sono state utilizzate dalle persone per mantenere tempi di calcolo ragionevoli quando si lavora con set di dati di grandi dimensioni?
  • Esistono metodi raccomandati dall'ESRI che mi sono perso nella mia ricerca di ottimizzazione?

    Comprendo le spese generali sostenute durante la creazione di un cursore arcgisscripting, in particolare se proviene da un geodatabase personale, anche se dopo una lunga ricerca di risposte relative alle prestazioni da questo sito e Google, ho l'impressione che le prestazioni non siano in prima linea negli sforzi delle persone .

  • Come utente dei prodotti ESRI, ci si può aspettare e perdonare questi ritardi nelle prestazioni?

AGGIORNARE

Dopo alcuni lavori con questo prodotto ho accumulato un elenco di tecniche di ottimizzazione che hanno portato a un processo di conversione delle informazioni spaziali da un formato proprietario a un geodatabase. Questo è stato sviluppato per geodatabase personale e di file. tidbits:

  1. Leggi i tuoi dati e razionalizzali in memoria. Questo ridurrà il tuo tempo a metà.

  2. Creare classi di funzioni e tabelle in memoria. Utilizzare il keywork del set di dati delle funzionalità 'in_memory' per utilizzare la memoria come disco ram, eseguire lì le proprie funzioni e quindi scrivere su disco

  3. Per scrivere su disco, utilizzare CopyFeatureclass per le classi di entità geografiche e CopyRow per le tabelle.

Queste 3 cose hanno richiesto uno script che ha convertito oltre 100.000 funzionalità in un geodatabase da 30 minuti a 30 - 40 secondi, comprese le classi di relazione. Non devono essere usati alla leggera, la maggior parte dei metodi di cui sopra utilizza molta memoria, il che potrebbe causare problemi se non si presta attenzione.


1
Hai provato a utilizzare un formato di archiviazione diverso? Come funziona un geodatabase di file?
Derek Swingley,

Un geodatabase di file ha prestazioni leggermente peggiori di un geodatabase personale. Ho passato ieri a configurare e ottimizzare un'istanza di ArcSDE per testare le prestazioni su un formato aziendale. Vi terrò aggiornati sui miei risultati
OptimizePrime,

2
Questo non ti aiuta ora, ma in 10.1 le prestazioni del cursore in Python sono state migliorate di un fattore enorme (qualcosa nell'ordine di intervallo di magnitudo in casi medi) con il nuovo modulo di accesso ai dati.
Jason Scheirer,

In_memory utilizza un InMemoryWorkspace edndoc.esri.com/arcobjects/9.2/ComponentHelp/esriDataSourcesGDB/… che, dopo un numero arbitrario di righe, scarica tutto su una ScratchWorkspaceFactory (cioè FileGDB) e si affida a FileGDB per fare tutto il lavoro
Ragi Yaser Burhum,

Risposte:


56

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.


5
Grazie. Avrei dovuto lavorare invece di scrivere questo post ahah
Ragi Yaser Burhum,

3
+1 Grazie mille per il tuo contributo, onorevole Burhum. Questo è il tipo di risposta che intendevo ricevere. Se potessi votare due volte, potrei !! Ciò che gli utenti di ArcGISScripting (python) dovrebbero prendere da questa risposta è che, sebbene i collegamenti riflettano i concetti ArcObjects e .Net, gli oggetti COM sottostanti sono gli stessi, la comprensione di questi oggetti ti aiuterà a pianificare meglio il codice in qualsiasi lingua. Molte informazioni fantastiche qui !!
OptimizePrime

1
@OptimizePrime Questo è un ottimo riassunto. E hai ragione: non puoi ignorare le implicazioni di ArcObjects se vuoi spremere le prestazioni dai prodotti ESRI
Ragi Yaser Burhum

1
grazie, ho sostituito store () inserendo i cursori e risparmiato molto tempo nelle mie applicazioni!
superrache,

5

In generale, per i calcoli delle prestazioni, provo a stare lontano dall'uso di qualsiasi materiale correlato a ESRI. Per il tuo esempio, suggerirei di eseguire il processo in passaggi, il primo passaggio leggendo i dati in normali oggetti Python, facendo i calcoli e quindi l'ultimo passaggio convertendo il formato spaziale ESRI finale. Per ~ 10k record, probabilmente potresti evitare di archiviare tutto in memoria per l'elaborazione, il che darebbe un netto miglioramento delle prestazioni.


Grazie per la vostra risposta. È un buon suggerimento Ho iniziato a refactoring il codice per eseguire le procedure richieste prima di utilizzare arcgisscripting. Dopo aver lavorato con il software sin dai tempi di ArcInfo, trovo frustrante l'aumento delle prestazioni della CPU e dell'hardware, le prestazioni di ArcGIS Map / Info / Editor XX sono stagnanti. Forse l'introduzione delle GPU potrebbe dare impulso alle cose. Anche se un buon refattore della base di codice ESRI può aiutare anche
OptimizePrime,

1

A seconda dell'hardware che hai, potresti anche considerare l'opzione visualizzata nell'esempio di geocoder ESRI; ti dà un framework per suddividere un set di dati di grandi dimensioni ed eseguire più istanze di Python per darti quasi un approccio multi-thread. Ho visto le prestazioni di geocodifica andare da 180.000 all'ora in una singola istanza di Python a oltre un milione grazie alla rotazione di 8 processi paralleli sulla mia macchina.

Ho visto che allontanarsi il più possibile e mantenere il lavoro dei dati nel database e il lavoro funzionale nelle mie tabelle e usare semplicemente ciò che è esplicito GIS nel regno ESRI danno importanti miglioramenti delle prestazioni.


Queste sono grandi idee. Ho l'opportunità di infilare alcuni processi in questo script, ma sto scoprendo che i miei colli di bottiglia stanno inizializzando le librerie COM e l'I / O del geodatabase. Per quanto riguarda l'I / O, ho ridotto la necessità di una sola scrittura. Se avrò più tempo per l'ottimizzazione, il mio capo avrà una risposta;) Quindi lascerò il threading come ultima compressione della performance se ne chiederà di più. Al momento sto elaborando 60.000 funzioni al minuto.
OptimizePrime,

0

Potresti trovare interessanti altri post sul forum in quanto sono nel contesto di ottimizzazione, ma per i dati raster e in generale:

Compilare script Python che utilizzano gli strumenti di geoprocessing di ArcGIS?

Tempo di elaborazione con gli strumenti della toolbox ArcGIS Hydrology in script Python autonomi vs ArcCatalog?

l'impostazione gp.scratchworkspace ha fatto una grande differenza per me in alcuni codici Python che ho scritto per fare delineazioni spartiacque.

Potresti pubblicare alcuni esempi di codice che dimostrano i numeri 1 e 2 nel tuo AGGIORNAMENTO alla domanda originale? Sarei interessato a vederne i meccanismi (anche se suppongo che tu abbia a che fare con i dati della classe di funzionalità solo qui)

grazie Tom

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.