Kompilieren von Python-Skripten (zu .exe), die ArcGIS-Geoverarbeitungswerkzeuge verwenden?


12

Ich programmiere jetzt seit einigen Monaten mit Python und habe einige einigermaßen komplexe Skripte für hauptsächlich Geoverarbeitungsaufgaben entwickelt. Davon abgesehen lerne ich immer noch viel, da ich einen SQL / VBA / VBScript-Hintergrund habe.

Ich weiß, dass kompilierter Code in der Regel schneller ausgeführt wird als Code, der von einem Sprachinterpreter verarbeitet werden muss. Daher bin ich an der Möglichkeit interessiert, ein Geoverarbeitungs-Python-Skript in eine EXE-Datei für die Arbeit mit Big Data zu kompilieren.

Ist das überhaupt möglich? Wenn dies der Fall ist, wie kann ein Python-Skript (.py), das die arcgisscript- oder arcpy-Module importiert, am besten kompiliert werden?

Ich habe ein paar Minuten lang versucht, das zu finden, was ich tun möchte, und die Suche ergab unter anderem den folgenden Artikel: http://www.ehow.com/how_2091641_compile-python-code.html

Der Compiler schien zu funktionieren, aber beim Ausführen der resultierenden .EXE-Datei trat ein kryptischer Fehler auf, der besagte, dass einige Dateien nicht verfügbar waren.

Das Python-Skript führt einigermaßen gut von der Befehlszeile aus, aber ich frage mich, ob ich eine leichte Verbesserung feststellen könnte, wenn ich die .py-Datei kompilieren könnte. Auch hier arbeite ich mit einigen großen Datensätzen, deren Verarbeitung +20 Stunden in Anspruch nimmt (Abgrenzung von Wassereinzugsgebieten von Probenorten mit Eingangswasserqualität). Ich werde alles nehmen, was ich für Verbesserungen tun kann.

Das Skript lief 10% schneller außerhalb von ArcGIS von der Befehlszeile einen Testsatz von Sites , die gegen die Einstellung der Skript nach oben als Script - Tool in einer neuen Toolbox in ArcCatalog. Ich habe das Skript über die Befehlszeile ausgeführt, ohne dass eine Instanz von ArcGIS auf einem dedizierten Computer geöffnet war.

Ist es also möglich, Python-Skripte zu kompilieren, die das arcgisscripting-Modul importieren und die ArcToolBox-Tools aufrufen?

BEARBEITEN

Danke für die Eingabe, das ist hilfreich für mich. Das Skript ist hauptsächlich eine Möglichkeit, eine Reihe von ArcGIS-Tools zu koordinieren und in gewünschten Formaten / Positionen / mit entsprechender Zuordnung auszugeben. Ich habe bereits einiges an Fett abgeschnitten, indem ich in einen Scratch-Ordner anstelle einer Scratch-Personal-Geodatabase für einige Zwischen-Raster-Dateien geschrieben habe, damit sie im ESRI-GRID-Format im Vergleich zum IMG-Format gespeichert werden können. Ich werde jedoch die Profiler-Vorschläge überprüfen.

In meinem Büro gibt es einige, die Python fragen: "Dieser kompilierte Code ist so viel schneller als Code, der durch einen Interpreter läuft", hauptsächlich im Vergleich zu beispielsweise einem kompilierten Visual Basic-Programm oder einem VB.NET-Programm, aber das ist ein guter Punkt Die Werkzeuge werden in beiden Fällen einige Zeit in Anspruch nehmen. Und es scheint, als ob bei heutigen Computern der interpretierte Code nicht so viel langsamer ist als der kompilierte Code, um diese zusätzliche Meile zu rechtfertigen.

EDIT - Update zur Optimierung des Programms mit Rasterformaten.

Ich wollte meine "Optimierung" dieses Python-Programms fortsetzen und konnte 2 Stunden Verarbeitungszeit einsparen, indem ich Zwischen-Raster im GRID-Format anstelle einer persönlichen Geodatabase schrieb. Darüber hinaus wurde der Speicherplatzbedarf auf der Festplatte erheblich reduziert. Der ursprüngliche Lauf, in dem ich alle Raster geschrieben habe (und es handelte sich nur um Punkt-Features, die in Raster konvertiert wurden, und dann um Watershed-Raster), ergab 37,1 GB Daten nur für diese Dateien. Das Schreiben der letzten beiden Datenausgaben in einen Ordner im GRID-Format wurde auf 667 MB Daten reduziert.

Ich wäre gespannt, wie eine GDB-Datei mit diesen Daten umgehen würde, allerdings hauptsächlich in Bezug auf die Größe der Daten. Die Verkürzung der Verarbeitungszeit von 9,5 auf 7,5 Stunden reicht jedoch aus, um Raster außerhalb von Geodatabases im GRID-Format zu verarbeiten.


Dieser Morgen ArcGIS Server Blog ist sehr aktuell. Sterling @ esri macht einen guten Job, wenn es darum geht, warum und wann [hier.] [1] [1]: blogs.esri.com/Dev/blogs/arcgisserver/archive/2011/04/12/…
Brad Nesom

Antworten:


15

Erste Frage: Wie viel davon machst du in Python? Wenden Sie sich nur an Geoverarbeitungswerkzeuge, oder führen Sie eine umfangreiche numerische Analyse in Python durch? In letzterem Fall sind die Engpässe wahrscheinlich auf die Tools zurückzuführen, und die Verwendung von nativem Code in Ihrem Skript kann Sie weniger kosten als einige andere clevere Problemumgehungen. Wenn letzteres der Fall ist, möchten Sie möglicherweise herausfinden, was langsam ist, und es mit besseren Algorithmen, möglicherweise Numpy oder einer anderen Option, wie unten beschrieben, beschleunigen.

py2exe nicht wirklich Ihren Code nativen x86 / x64 kompilieren, sondern bietet nur eine ausführbare Datei , die Ihr Skript als Bytecode bettet und stellt einen meist tragbaren Weg , um es die Benutzer , ohne Python auf ihren Systeme zu verteilen. Beim Versuch, arcgisscripting zu bündeln, ist dies fehlgeschlagen, weshalb es nicht funktioniert hat. Eigentlich reicht es nicht aus, py2exe zum Laufen zu bringen.

Ich empfehle dringend, zuerst einen Profiler zu verwenden, um die langsamen Bits zu identifizieren und von dort aus zu optimieren. In Python ist ein sehr gutes Set integriert . Verwenden Sie cProfile auf lange Sicht, um potenzielle Stellen zu finden, an denen es schneller geht. Von dort aus können Sie Abschnitte in benutzerdefiniertes C optimieren oder möglicherweise mit kleinen Abschnitten als Cython .pyx-Module experimentieren .

Sie können in Cython nachsehen, ob Sie möglicherweise das gesamte Python-Skript als systemeigenes Code-Erweiterungsmodul erstellen. Psyco kann Ihnen jedoch auch eine Leistungssteigerung mit einer geringeren Eintrittsbarriere bieten.


4

Wie lange dauert die Abgrenzung der Wasserscheide, wenn sie mit den Standardwerkzeugen in ArcToolbox im Vergleich zur Skriptversion ausgeführt wird? Wenn die Zeiten ähnlich sind, dann vermute ich, dass es keine Besserung geben wird. Möglicherweise möchten Sie lange Prozesse im Hintergrund außerhalb von ArcMap ausführen.


Ich habe meine ursprüngliche Frage geklärt und hoffe immer noch eine Ja / Nein-Antwort zu erhalten. Ist es möglich, einen solchen Code zu kompilieren, da diese Antwort meine Frage nicht beantwortet?
Turkishgold

2
@turkish Es kann sein, dass Ihre Frage nicht direkt beantwortet wird, aber es ist ein ausgezeichneter Vorschlag. Die Chancen stehen gut, dass Ihr Prozess seine gesamte Zeit in die Abgrenzung investiert. Daher hilft es kaum, den Code zu optimieren. Eine erneute Überprüfung des Algorithmus könnte jedoch einen großen Unterschied bewirken. Eines der ersten Dinge, die Sie tun möchten, ist das Profilieren der aktuellen Ausführung, um festzustellen, ob Sie Ihre Zeit mit diesem Kompilierungsansatz verschwenden.
Whuber

1
Ich stimme mit @Dan und @whuber überein. Ich denke, dass eine gründlichere Analyse (dh Benchmarking und Profiling) viel bessere Erkenntnisse für Leistungsverbesserungen liefert als nur ein Brute-Force-Compile-Alles-Ansatz.
Jason Scheirer

4

Verwenden Sie keine Personal Geodatabase ohne guten Grund. Nach unserer Erfahrung sind sie durchweg viel langsamer als alle anderen Arten der Speicherung von esri-Daten ( ref ). Obwohl ich hier auf GIS.se einen Bericht gelesen habe, der schneller als die Datei gdb aussah.

Wenn der Workflow aus vielen kleinen Iterationen besteht, ist der Aufruf zum Erstellen des Geoprozessors und zum Auschecken einer Lizenz häufig der zeitaufwendigste Teil der Verwendung von Python. So viel wie möglich vor oder hinter gp = ...(oder import arcpyin Version 10) zu tun, ist eine Technik, die ich häufig verwende.

In Bezug auf das Kompilieren sagt dieses Zitat am besten aus:

Es ist erwähnenswert, dass , während eine kompilierte [Python] Skript läuft eine schnellere hat Startzeit (da es nicht kompiliert werden muss), es nicht laufen schneller.

Mark Cederholm hält eine Präsentation zur Verwendung von ArcObjects in Python mit einigen Statistiken zu Shapecopy-Vorgängen (Folie 4). Python ist mit 32% der mit C ++ erreichbaren Leistung nicht besonders gut (VBA lag bei 92%, VB & C # bei 48%). Laufen Sie nicht zu schnell und schreien Sie. Viele der Geoverarbeitungswerkzeuge sind ohnehin Python-Skripte (durchsuchen Sie C: \ Programme \ Arcgis \ nach '* .py').

Wie viele an anderen Orten bereits gesagt haben, übersteigt die Zeit, die mit Python verbracht wird, um die Leistung zu optimieren, indem eine C- oder C ++ - Kernfunktion kompiliert oder geschrieben wird, häufig die tatsächlichen (möglicherweise) zur Laufzeit erzielten Leistungssteigerungen. Viele sagen, Pythons Hauptvorteil bestehe darin, die Entwicklerzeit zu optimieren und zu verbessern . menschliche Aufmerksamkeit ist weitaus wertvoller und teurer als maschinelle Bearbeitungszeit.


1
Ja in jeder Hinsicht. Für mein Geld ist die optimale Nutzung der Entwicklerzeit der Prototyp * in Python, Benchmark, Dropdown in C / C ++, um Engpässe zu optimieren. * Ich sage Prototyp, aber ich weiß, dass der 'Prototyp' zu 95% in Produktion gehen wird.
Jason Scheirer

Tolle Kommentare und vielen Dank für die Links zu ArcObjects in Python. Ich denke, das Schreiben in eine GDB hat Vorteile aus der Perspektive der Datenverwaltung im Vergleich zu Shapefile (Attributtabelleneinschränkungen in Shapefiles im Vergleich zu Feature-Classes, Geometriedarstellung, allgemeine Datenverwaltungspraktiken usw.) sowie aus Aspekten, die Sie viel einfacher und sauberer ausführen können eine Access-Umgebung im Vergleich zum Umgang mit DBF-Dateien. Im Grunde genommen also ein Kosten-Nutzen-Kompromiss mit dem, was Sie tun und was Sie mit den Ausgabedaten tun werden. Der Mittelweg zwischen Rastern außerhalb von GDB und allem anderen in GDB scheint zu funktionieren.
Turkishgold

1

Sie können Python-Code nicht zu Maschinencode kompilieren. Wenn es zum ersten Mal ausgeführt wird, wird es zu 'bytecode' kompiliert, einer Zwischensprache (die pyc-Dateien erstellt).

py2exe packt die vom Interpreter benötigten DLL-Dateien und alle erforderlichen Python-Dateien / externen Dateien in eine ausführbare Datei. Es wird nicht kompiliert - die Laufzeit sollte nicht viel anders sein.

Es ist möglich, Python-Code mithilfe einer Kombination verschiedener Techniken sehr schnell laufen zu lassen.

Als erstes sollten Sie Ihren Code profilieren, um die Engpässe zu finden. Einmal gefunden, verwende ich normalerweise diesen Prozess:

  • Beseitigen Sie For-Schleifen, indem Sie Numpy-Arrays oder die map () -Funktion verwenden. Dies drückt im Grunde die Schleife in C.
  • Untersuchen Sie bessere Implementierungen des Algorithmus (diese Art von geht mit dem oben genannten einher). Dinge wie das Reduzieren der Anzahl von E / A-Operationen, um sicherzustellen, dass auf Daten in zusammenhängenden Blöcken zugegriffen wird / diese gespeichert werden.
  • Interpreter-Tricks wie das Vermeiden teurer Suchvorgänge innerhalb von Schleifen und das Vermeiden von 'if'-Blöcken innerhalb von Schleifen (verwenden Sie stattdessen' try ')
  • Profiliere es noch einmal
  • Wenn es immer noch zu langsam ist, versuchen Sie, kritische Teile mit Cython in C zu verschieben (oder schreiben Sie direkt in C, erstellen Sie eine DLL und rufen Sie sie mit ctypes auf).
  • Wieder ein Profil
  • Wenn Sie immer noch zu langsam sind, schauen Sie sich Parallel- oder GPU-Computing an (Multiprocessing Library, pyCUDA, ParallelPython usw.).

0

Wenn Sie ein Python-Skript von einem anderen Speicherort importieren, wird eine .pyc-Datei generiert. Eine einfache Möglichkeit zu testen, ob das Kompilieren einen Unterschied macht, besteht darin, Ihr Skript in eine Funktion (z. B. main ()) umzuwandeln. Wenn Sie dieses Skript als speichern, example.pyerstellen Sie eine weitere Datei mit den folgenden Zeilen:

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

Wenn Sie das Skript zeitweise ausführen und es beim Importieren ausführen, können Sie möglicherweise den Unterschied erkennen. Dies ist jedoch eine Low-Tech-Methode.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.