Compilare script Python (in .exe) che utilizzano ArcGIS Geoprocessing Tools?


12

Ho programmato con Python per diversi mesi e ho sviluppato alcuni script ragionevolmente complessi per attività principalmente di geoprocessing. Detto questo, sto ancora imparando molto dal momento che provengo da un background SQL / VBA / VBScript.

So che il codice compilato in genere viene eseguito più velocemente del codice che deve essere elaborato da un interprete di lingue, quindi sono interessato alla possibilità di compilare uno script Python geoprocessore in un file .EXE per lavorare con i big data.

È possibile? In tal caso, qual è il modo migliore per compilare uno script Python (.py) che sta importando i moduli arcgisscripting o arcpy?

Ho impiegato alcuni minuti a cercare quello che volevo fare e la ricerca ha restituito questo articolo, tra gli altri: http://www.ehow.com/how_2091641_compile-python-code.html

Il compilatore sembrava funzionare, ma dopo aver eseguito il file .EXE risultante, ha generato un errore criptico che diceva che alcuni file non erano disponibili.

Lo script Python esegue ciò che sembra ragionevolmente bene dalla riga di comando, ma mi chiedo se potrei vedere qualche leggero miglioramento se fossi in grado di compilare il file .py. Ancora una volta, sto lavorando con alcuni grandi set di dati che impiegano +20 ore per l'elaborazione (delineando gli spartiacque dai siti di campionamento della qualità dell'acqua di input). Prenderò tutto ciò che posso in termini di miglioramenti.

Lo script è stato eseguito il 10% più rapidamente al di fuori di ArcGIS dalla riga di comando utilizzando un set di test di siti rispetto all'impostazione dello script come strumento di script in un nuovo toolbox in ArcCatalog. Ho eseguito lo script dalla riga di comando senza alcuna istanza di ArcGIS aperta su una macchina dedicata.

Quindi, è possibile compilare script Python che importano il modulo arcgisscripting e che chiamano strumenti ArcToolBox?

MODIFICARE

Grazie per l'input, questo è utile per me. Lo script è in gran parte un modo per coordinare una serie di strumenti ArcGIS e per produrre nei formati / posizioni desiderati / con l'attribuzione appropriata. Ho già ridotto un po 'di grasso, penso scrivendo in una cartella scratch anziché in un geodatabase personale scratch per alcuni file raster temporanei in modo che possano essere memorizzati nel formato ESRI GRID rispetto al formato IMG. Vedrò comunque i suggerimenti del profiler.

Ci sono alcuni nel mio ufficio che pongono domande a Python dicendo "che il codice compilato è molto più veloce del codice che scorre attraverso un interprete" principalmente rispetto, per esempio, a un programma compilato Visual Basic o VB.NET, ma è un buon punto che gli strumenti impiegheranno del tempo in entrambi i modi. E sembra che con le attuali macchine di calcolo che interpretare il codice potrebbe non essere molto più lento del codice compilato per giustificare quel miglio in più.

EDIT - aggiornamento sull'ottimizzazione del programma con formati raster.

Volevo dare seguito alla mia "ottimizzazione" di questo programma Python e sono stato in grado di radere 2 ore di tempo di elaborazione scrivendo raster intermedi in formato GRID anziché in un geodatabase personale. Non solo, si è verificata una significativa RIDUZIONE del consumo di spazio su disco per le dimensioni dei dati. La corsa originale che ho fatto scrivendo tutti i raster (ed erano solo funzioni punto convertite in raster e quindi raster spartiacque) ha prodotto 37,1 GB di dati solo per quei file. La scrittura di questi ultimi due output di dati in una cartella in formato GRID è stata ridotta a 667 MB di dati.

Sarei curioso di vedere come un file GDB gestirà questi dati anche se principalmente in base alla dimensione dei dati. Tuttavia, ridurre i tempi di elaborazione da 9,5 ore a 7,5 ore è sicuramente sufficiente per sostenere la gestione di raster al di fuori dei database geografici nel formato GRID.


Questa mattina Blog ArcGIS Server è di grande attualità. Sterling @ esri fa un buon lavoro nel delineare perché e quando [qui.] [1] [1]: blogs.esri.com/Dev/blogs/arcgisserver/archive/2011/04/12/…
Brad Nesom

Risposte:


15

Prima domanda: quanto stai facendo in Python? Stai solo chiamando gli strumenti di Geoprocessing o stai eseguendo una notevole quantità di analisi numeriche in Python? Se il primo, i colli di bottiglia risiedono probabilmente negli strumenti e l'uso di codice nativo nel tuo script non ti acquisterà tanto quanto qualche altra soluzione intelligente. Se quest'ultimo, allora potresti voler trovare ciò che è lento e renderlo più veloce con algoritmi migliori, o forse intorpidito, o qualche altra opzione come discusso di seguito.

py2exe in realtà non compila il codice in nativo x86 / x64, fornisce semplicemente un eseguibile che incorpora lo script come bytecode e fornisce un modo per lo più portatile di distribuirlo agli utenti senza Python sui loro sistemi. Ha fallito quando ha tentato di raggruppare arcgisscripting, motivo per cui non ha funzionato. Far funzionare py2exe in realtà non funzionerà ancora in termini di prestazioni.

Consiglio vivamente di utilizzare prima un profiler per identificare i bit lenti e ottimizzare da lì. C'è un ottimo set integrato in Python , usa cProfile a lungo termine per trovare potenziali posti per renderlo più veloce. Da lì puoi ottimizzare le sezioni in C personalizzate o eventualmente sperimentare piccole porzioni come moduli Cython .pyx.

Puoi cercare in Cython la possibilità di creare l'intero script Python come modulo di estensione del codice nativo, ma Psyco potrebbe anche darti un aumento delle prestazioni con una barriera inferiore all'ingresso.


4

Quanto tempo impiega la delineazione dello spartiacque se eseguita dagli strumenti standard in ArcToolbox rispetto alla versione dello script? Se i tempi sono simili, sospetto che non ci saranno miglioramenti. Potresti prendere in considerazione l'esecuzione di lunghi processi in background al di fuori di ArcMap.


Ho chiarito la mia domanda originale e spero di ottenere ancora una risposta affermativa sì / no, è possibile compilare un codice in quanto questa risposta non risponde alla mia domanda.
turkishgold,

2
@turkish Potrebbe non rispondere direttamente alla tua domanda, ma è un suggerimento eccellente. È probabile che il processo passi tutto il suo tempo nella delimitazione, quindi nessuna modifica del codice sarà di grande aiuto. Tuttavia, riconsiderare l' algoritmo potrebbe fare una differenza enorme. Quindi una delle prime cose che vuoi fare è profilare l'esecuzione corrente per vedere se stai perdendo tempo con questo approccio di compilazione.
whuber

1
Sono d'accordo con @Dan e @whuber. Penso che fare un'analisi più approfondita (ad esempio benchmarking e profiling) fornirà una visione molto migliore per i miglioramenti delle prestazioni rispetto a un semplice approccio per la compilazione di qualsiasi forza bruta.
Jason Scheirer,

4

Non utilizzare un geodatabase personale senza una buona ragione. Nella nostra esperienza sono costantemente molto più lenti di tutte le altre forme di archiviazione dei dati esri ( ref ). Anche se ho letto un rapporto qui su GIS.se che ha visto personale più veloce del file gdb.

Quando il flusso di lavoro è costituito da molte piccole iterazioni, la chiamata per creare il geoprocessore e verificare una licenza è spesso la parte più costosa dell'uso di Python. Quindi fare il più possibile davanti o dietro gp = ...(o import arcpyin v10) è una tecnica che uso molto.

Per quanto riguarda la compilazione, questa citazione lo dice meglio:

Vale la pena notare che durante l'esecuzione di uno script [python] compilato ha un tempo di avvio più rapido (in quanto non è necessario compilarlo), non viene eseguito più velocemente.

Mark Cederholm ha una presentazione sull'uso di ArcObjects in Python con alcune statistiche sulle operazioni di shapecopy (slide # 4). Python non funziona molto bene, con il 32% di ciò che si può ottenere con C ++ (VBA era del 92%, VB e C # al 48%). Non correre e urlare troppo in fretta, molti degli strumenti di geoprocessing sono comunque script di Python (cerca c: \ programmi \ arcgis \ per '* .py').

Come molti hanno già detto in altre sedi, con Python il tempo speso nel tentativo di ottimizzare le prestazioni compilando o scrivendo una funzione di base C o C ++ spesso sminuisce qualsiasi reale guadagno in termini di prestazioni (possibilmente) realizzato in fase di runtime. Molti sostengono che il principale vantaggio di Python sia l'ottimizzazione e il miglioramento dei tempi degli sviluppatori ; l'attenzione umana è di gran lunga più preziosa e costosa dei tempi di lavorazione della macchina.


1
Sì su tutti i fronti. Per quanto mi riguarda, l'uso ottimale del tempo degli sviluppatori è di prototipare * in Python, benchmark, scendere a C / C ++ per ottimizzare i colli di bottiglia. * Dico prototipo, ma conosco il 95% delle volte che il "prototipo" sarà destinato alla produzione.
Jason Scheirer,

Grandi commenti e grazie per i collegamenti su ArcObjects in Python. Penso che scrivere su un GDB abbia benefici dal punto di vista della gestione dei dati rispetto allo shapefile (restrizioni della tabella degli attributi negli shapefile rispetto alle classi di feature, alla rappresentazione della geometria, alle pratiche generali di gestione dei dati, ecc.) Così come alle cose in cui puoi fare molto più facilmente e in modo più pulito un ambiente Access rispetto alla gestione dei file DBF. Quindi, fondamentalmente un compromesso costi-benefici con ciò che stai facendo e che cosa hai a che fare con i dati di output. La via di mezzo dei raster al di fuori di GDB e tutto il resto in GDB sembra funzionare.
turkishgold

1

Non è possibile compilare il codice Python in codice macchina. Quando viene eseguito per la prima volta, viene compilato in 'bytecode', un linguaggio intermedio (che crea file pyc)

py2exe racchiude in un file eseguibile i file dll richiesti dall'interprete e tutti i file python / file esterni richiesti. Non è compilato - il runtime non dovrebbe essere molto diverso.

È possibile eseguire il codice Python molto velocemente, utilizzando una combinazione di tecniche diverse.

La prima cosa da fare è profilare il codice per trovare i colli di bottiglia. Una volta trovato, di solito utilizzo questo processo:

  • Elimina i cicli 'for' usando array intorpiditi o la funzione map (). Questo sostanzialmente spinge il ciclo in C.
  • Indagare su migliori implementazioni dell'algoritmo (questo tipo di va di pari passo con quanto sopra). Roba come ridurre il numero di operazioni I / O, garantendo l'accesso / memorizzazione dei dati in blocchi contigui.
  • "Trucchi" dell'interprete come evitare ricerche costose all'interno dei loop, evitando blocchi "if" all'interno dei loop (utilizzare invece "try")
  • Profilalo di nuovo
  • Se è ancora troppo lento, guarda spingendo le parti critiche in C usando Cython (o scrivendo direttamente in C, creando una dll e usando i ctypes per chiamarla)
  • Profilo di nuovo
  • Se è ancora troppo lento, guarda il calcolo parallelo o GPU (libreria multiprocessore, pyCUDA, ParallelPython ecc.)

0

Se importi uno script Python da un'altra posizione, genera un file .pyc. Quindi, un modo semplice per verificare se la compilazione fa la differenza sarebbe trasformare il tuo script in una funzione (ad es. Main ()). Se si salva quello script come example.pyquindi creare un altro file con le seguenti righe:

import example
example.main() # call your script(s)

Se esegui il tempo all'interno dello script e quando viene importato, forse puoi vedere qual è la differenza. Questo è un modo a bassa tecnologia di farlo però.

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.