Kompilujesz skrypty Pythona (do .exe) korzystające z narzędzi geoprzetwarzania ArcGIS?

12

Od kilku miesięcy programuję w Pythonie i opracowałem dość złożone skrypty do zadań geoprzetwarzania. To powiedziawszy, wciąż dużo się uczę, ponieważ pochodzę z języka SQL / VBA / VBScript.

Wiem, że skompilowany kod zazwyczaj działa szybciej niż kod, który musi być przetworzony przez interpretera języka, dlatego interesuje mnie możliwość skompilowania geoprzetwarzającego skryptu Python do pliku .EXE do pracy z dużymi danymi.

Czy to w ogóle możliwe? Jeśli tak, to jaki jest najlepszy sposób na skompilowanie skryptu Python (.py), który importuje moduły arcgisscripting lub arcpy?

Spędziłem kilka minut, szukając tego, co chcę zrobić, a wyszukiwanie zwróciło ten artykuł między innymi: http://www.ehow.com/how_2091641_compile-python-code.html

Kompilator wydawał się działać, ale po uruchomieniu wynikowego pliku .EXE wystąpił tajemniczy błąd informujący, że niektóre pliki były niedostępne.

Skrypt w Pythonie działa z wiersza poleceń, co wydaje się być całkiem dobre, ale zastanawiam się, czy mógłbym zobaczyć jakąś poprawę w przypadku skompilowania pliku .py. Ponownie pracuję z niektórymi dużymi zestawami danych, których przetwarzanie zajmuje więcej niż 20 godzin (wyznaczanie działów wodnych z wejściowych miejsc próbnych jakości wody). Wezmę wszystko, co mogę, aby ulepszyć.

Skrypt działał 10% szybciej poza ArcGIS z wiersza poleceń, używając zestawu testowego stron, w porównaniu do ustawienia skryptu jako narzędzia skryptowego w nowym zestawie narzędzi w ArcCatalog. Uruchomiłem skrypt z wiersza poleceń bez żadnego wystąpienia ArcGIS otwartego na dedykowanym komputerze.

Czy można więc skompilować skrypty Pythona, które importują moduł arcgisscripting i wywołują narzędzia ArcToolBox?

EDYTOWAĆ

Dzięki za wkład, to jest dla mnie pomocne. Skrypt jest w dużej mierze sposobem na koordynację wielu narzędzi ArcGIS i generowanie danych w pożądanych formatach / lokalizacjach / z odpowiednią atrybucją. Wydaje mi się, że już przyciąłem trochę tłuszczu, pisząc w folderze scratch zamiast scratch osobistej geobazy dla niektórych tymczasowych plików rastrowych, aby mogły być przechowywane w formacie ESRI GRID w porównaniu z formatem IMG. Sprawdzę jednak sugestie profilera.

W moim biurze jest kilka osób, które pytają Pythona, mówiąc: „skompilowany kod jest o wiele szybszy niż kod uruchamiany przez interpreter” głównie w porównaniu, powiedzmy, ze skompilowanego programu Visual Basic lub programu VB.NET, ale to dobrze, że narzędzia zabiorą trochę czasu. I wydaje się, że w dzisiejszych maszynach komputerowych interpretowany kod może nie być znacznie wolniejszy niż skompilowany kod, aby zagwarantować, że przejdzie się o krok dalej.

EDYCJA - aktualizacja dotycząca optymalizacji programu o formatach rastrowych.

Chciałem kontynuować moją „optymalizację” tego programu w języku Python i mogłem zaoszczędzić 2 godziny czasu przetwarzania, pisząc tymczasowe rastry w formacie GRID zamiast na osobistej geobazie. Co więcej, nastąpiło znaczące zmniejszenie zużycia miejsca na dysku w rozmiarze danych. Pierwotny przebieg, w którym napisałem wszystkie rastry (i były to tylko cechy punktowe przekonwertowane na rastry, a następnie rastry z przełomem) dały 37,1 GB danych tylko dla tych plików. Zapis dwóch ostatnich danych wyjściowych do folderu w formacie GRID został zredukowany do 667 MB danych.

Byłbym ciekawy, jak plik GDB poradziłby sobie z tymi danymi, chociaż głównie ze względu na ich rozmiar. Ale skrócenie mojego czasu przetwarzania z 9,5 godziny do 7,5 godziny z pewnością wystarcza, aby opowiedzieć się za rastrami spoza geobaz danych w formacie GRID.

turkishgold
źródło
Ten poranek Blog ArcGIS Server jest bardzo aktualny. Sterling @ esri dobrze wyjaśnia, dlaczego i kiedy [tutaj.] [1] [1]: blogs.esri.com/Dev/blogs/arcgisserver/archive/2011/04/12/…
Brad Nesom

Odpowiedzi:

15

Pierwsze pytanie: ile z tego robisz w Pythonie? Czy tylko wołasz do narzędzi Geoprocessing, czy robisz znaczną liczbę analiz numerycznych w Pythonie? Jeśli to pierwsze, wąskie gardła prawdopodobnie znajdują się w narzędziach, a użycie natywnego kodu w skrypcie nie zapewni Ci tyle, co inne sprytne obejścia. Jeśli to drugie, możesz chcieć znaleźć to, co jest powolne i przyspieszyć dzięki lepszym algorytmom, ewentualnie numpy lub innej opcji, jak omówiono poniżej.

py2exe nie kompiluje twojego kodu do natywnego x86 / x64, po prostu zapewnia plik wykonywalny, który osadza twój skrypt jako kod bajtowy i zapewnia w większości przenośny sposób dystrybucji go wśród użytkowników bez Pythona w ich systemach. Nie powiodło się, gdy próbowano dołączyć pakiet arcgisscripting, dlatego nie zadziałało. Właściwie uruchomienie py2exe nadal nie zrobi nic pod względem wydajności.

Bardzo zdecydowanie polecam najpierw użyć profilera do zidentyfikowania wolnych bitów i stamtąd optymalizacji. Istnieje bardzo dobry zestaw wbudowany w Python , użyj cProfile na dłuższą metę, aby znaleźć potencjalne miejsca, aby przyspieszyć. Stamtąd możesz zoptymalizować oddalone sekcje do niestandardowego C lub eksperymentować z małymi porcjami jako moduły .pyx Cython.

Możesz zajrzeć do Cython pod kątem możliwości zbudowania całego skryptu Python jako natywnego modułu rozszerzenia kodu, ale Psyco może również zwiększyć wydajność przy niższej barierze wejścia.

Jason Scheirer
źródło
4

Ile czasu zajmuje przełom w przypadku uruchomienia ze standardowych narzędzi w ArcToolbox w porównaniu do wersji skryptu? Jeśli czasy są podobne, podejrzewam, że nie będzie poprawy. Możesz rozważyć uruchomienie długich procesów w tle poza ArcMap.


źródło
Wyjaśniłem moje pierwotne pytanie i mam nadzieję, że nadal otrzymam twierdzącą odpowiedź tak / nie, czy można skompilować taki kod, ponieważ ta odpowiedź nie odpowiada na moje pytanie.
turkishgold
2
@turkish To może nie odpowiedzieć bezpośrednio na twoje pytanie, ale jest to doskonała sugestia. Szanse są spore, że Twój proces spędza cały czas na kreśleniu, więc żadna modyfikacja kodu nie pomoże. Jednak ponowne rozważenie algorytmu może mieć ogromną różnicę. Tak więc jedną z pierwszych rzeczy, które chcesz zrobić, jest profilowanie bieżącego wykonania, aby zobaczyć, czy marnujesz czas dzięki temu podejściu do kompilacji.
whuber
1
Zgadzam się z @Dan i @whuber. Myślę, że głębsza analiza (tj. Analiza porównawcza i profilowanie) da znacznie lepszy wgląd w poprawę wydajności niż tylko podejście polegające na kompilacji wszystkiego za pomocą brutalnej siły.
Jason Scheirer,
4

Nie używaj osobistej geobazy bez uzasadnionego powodu. Z naszego doświadczenia wynika, że ​​są one znacznie wolniejsze niż wszystkie inne formy przechowywania danych esri ( ref ). Chociaż przeczytałem tutaj jeden raport na GIS.se, który widział szybszy osobisty niż plik gdb.

Gdy przepływ pracy składa się z wielu małych iteracji, wezwanie do utworzenia geoprocesora i sprawdzenia licencji jest często najdroższą częścią korzystania z Pythona. Więc robienie jak najwięcej z przodu lub z tyłu gp = ...(lub import arcpyw wersji 10) to jedna z technik, z której często korzystam.

W odniesieniu do kompilacji ten cytat najlepiej mówi:

Warto zauważyć, że podczas pracy skompilowany [python] skrypt ma szybszego uruchamiania czas (jak to nie musi być kompilowany), to nie działać szybciej.

Mark Cederholm ma prezentację na temat używania ArcObjects w Pythonie z pewnymi statystykami na temat operacji kształtowania (slajd nr 4). Python nie działa zbyt dobrze, działając przy 32% tego, co można osiągnąć w C ++ (VBA wynosił 92%, VB i C # przy 48%). Nie biegaj i nie krzycz zbyt szybko, wiele narzędzi geoprzetwarzania i tak jest skryptami python (szukaj c: \ program files \ arcgis \ dla '* .py').

Jak wielu powiedziało w innych miejscach, w Pythonie czas poświęcony na optymalizację wydajności poprzez kompilację lub napisanie funkcji podstawowej C lub C ++ często przewyższa wszelkie rzeczywiste przyrosty wydajności (możliwe) osiągnięte w czasie wykonywania. Wielu twierdzi, że główną korzyścią Pythona jest optymalizacja i skrócenie czasu programowania ; ludzka uwaga jest znacznie cenniejsza i droższa niż czas obróbki maszynowej.

matowe wilkie
źródło
1
Tak, pod każdym względem. Za moje pieniądze optymalne wykorzystanie czasu programisty to prototypowanie * w Pythonie, test porównawczy, upuszczanie do C / C ++ w celu optymalizacji wąskich gardeł. * Mówię prototyp, ale wiem, że w 95% przypadków „prototyp” trafi do produkcji.
Jason Scheirer,
Świetne komentarze i podziękowania za linki do ArcObjects w Pythonie. Myślę, że pisanie do GDB ma zalety z perspektywy zarządzania danymi w porównaniu do pliku shapefile (ograniczenia tabeli atrybutów w plikach shap vs. vs. klasy obiektów, reprezentacja geometrii, ogólne praktyki zarządzania danymi itp.), A także rzeczy, które możesz zrobić o wiele łatwiej i łatwiej środowisko Access vs. obsługa plików DBF. Zasadniczo jest to kompromis kosztów i korzyści z tym, co robisz i co będziesz musiał zrobić z danymi wyjściowymi. Środek rastrów poza GDB i wszystko inne w GDB wydaje się działać.
turkishgold,
1

Nie można skompilować kodu Pythona do kodu maszynowego. Kiedy uruchamia się po raz pierwszy, jest kompilowany do „kodu bajtowego”, języka pośredniego (który tworzy pliki pyc)

py2exe otacza pliki dll wymagane przez interpreter i wszelkie wymagane pliki python / pliki zewnętrzne do pliku wykonywalnego. Nie jest skompilowany - środowisko uruchomieniowe nie powinno się znacznie różnić.

Możliwe jest bardzo szybkie uruchamianie kodu w języku Python przy użyciu kombinacji różnych technik.

Pierwszą rzeczą, którą powinieneś zrobić, to profilować swój kod, aby znaleźć wąskie gardła. Po znalezieniu zwykle używam tego procesu:

  • Wyeliminuj pętle „for”, używając tablic numpy lub funkcji map (). To zasadniczo popycha pętlę do C.
  • Zbadaj lepsze implementacje algorytmu (ten rodzaj idzie w parze z powyższym). Rzeczy takie jak zmniejszenie liczby operacji we / wy, zapewniające dostęp do danych / przechowywanie ich w ciągłych blokach.
  • „Sztuczki” interpretera, takie jak unikanie kosztownych wyszukiwań w pętlach, unikanie blokowania „jeśli” w pętlach (zamiast tego użyj „try”)
  • Profiluj to ponownie
  • Jeśli nadal jest zbyt wolny, spójrz na wpychanie krytycznych części do C przy użyciu Cython (lub pisanie bezpośrednio w C, tworzenie dll i używanie ctypów do wywołania go)
  • Profiluj ponownie
  • Jeśli nadal jest zbyt wolny, spójrz na obliczenia równoległe lub GPU (biblioteka wieloprocesowa, pyCUDA, ParallelPython itp.)
James
źródło
0

Jeśli importujesz skrypt Pythona z innej lokalizacji, generuje on plik .pyc. Jednym z łatwych sposobów sprawdzenia, czy kompilacja ma znaczenie, byłoby przekształcenie skryptu w funkcję (np. Main ()). Jeśli zapiszesz ten skrypt jako, example.pya następnie utwórz inny plik z następującymi wierszami:

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

Jeśli czas biegnie z poziomu skryptu i jest uruchamiany podczas jego importowania, być może zobaczysz różnicę. Jest to jednak mało zaawansowany technologicznie sposób.

djq
źródło