Czy Python to aby na pewno wąskie gardło?
Mam dość artykułów, w których twierdzi się, że Python umiera. Pełna jawność — obecnie pracuję jako inżynier z Pythonem, więc możecie uznać mnie za stronniczą w tej kwestii, jednak chciałabym skomentować kilka krytycznych uwag na temat Pythona i zastanowić się, czy obawy dotyczące prędkości są uzasadnione w codziennej pracy w inżynierii danych, nauce o danych i analityce.
Czy Python jest zbyt wolny?
Z mojej perspektywy takie pytania powinny być zadawane w oparciu o konkretny kontekst lub przypadek użycia. Czy Python jest powolny w obliczaniu liczb w porównaniu z językami kompilowanymi, takimi jak C? Tak, jest. Fakt ten znany jest od lat i to właśnie dlatego biblioteki Pythona, dla których szybkość działania odgrywa ważną rolę, takie jak numpy, wykorzystują pod maską język C.
Ale czy Python jest dużo wolniejszy od innych (trudniejszych do nauczenia się i zastosowania) języków dla wszystkich przypadków użycia? Jeśli spojrzysz na benchmarki wydajności wielu bibliotek Pythona zoptymalizowanych do rozwiązywania konkretnych problemów, to radzą sobie one całkiem nieźle w porównaniu z językami kompilowanymi. Spójrz na przykład na benchmark wydajności FastAPI — oczywiście Go jako język kompilowany jest znacznie szybszy niż Python. Mimo to FastAPI bije na głowę niektóre biblioteki Go przy budowania REST API:
Tak na marginesie: powyższa lista nie uwzględnia frameworków do tworzenia aplikacji webowych C++ i Javy, które miały jeszcze lepszą wydajność.
Podobna sytuacja — porównując Dask (napisany w Pythonie) ze Sparkiem (napisanym w Scali) dla wymagających przetworzenia dużej ilości danych potoków neuroobrazowania, autorzy doszli do wniosku:
Ogólnie rzecz biorąc, nasze wyniki nie wykazują znaczącej różnicy w wydajności pomiędzy silnikami.
Pytanie, które powinniśmy sobie zadać, brzmi: jaka prędkość nas usatysfakcjonuje. Jeśli uruchamiasz zadanie ETL wyzwalane tylko raz dziennie, możesz nie zwracać uwagi na to, czy trwa ono 20 czy 200 sekund. Możesz wtedy preferować, aby kod był łatwy do zrozumienia, spakowania i utrzymania, w szczególności biorąc pod uwagę, że zasoby obliczeniowe stają się coraz bardziej opłacalne w porównaniu do kosztownego czasu inżynierii.
Szybkość kodowania a praktyczność
Z pragmatycznego punktu widzenia, istnieje szereg różnych pytań, na które musimy sobie odpowiedzieć, wybierając język programowania do codziennej pracy.
Czy można solidnie rozwiązać wiele problemów biznesowych za pomocą tego języka?
Jeśli zależy Ci tylko na szybkości, to nie używaj Pythona, koniec kropka. Istnieją o wiele szybsze alternatywy dla każdego rodzaju przypadku użycia. Główne zalety Pythona to jego czytelność, łatwość zastosowania i szeroki zakres problemów, które można rozwiązać z jego pomocą. Python może być rozumiany jako klej, który łączy niezliczoną ilość różnych systemów, usług i przypadków użycia.
Czy znajdziesz wystarczająco dużo pracowników, którzy znają ten język?
Liczba użytkowników Pythona stale rośnie, ponieważ jest łatwy w nauce i użytkowaniu. Użytkownicy biznesowi, którzy wcześniej liczyli liczby w Excelu, mogą teraz szybko nauczyć się kodować w Pandas i w ten sposób nauczyć się być samowystarczalnym, nie polegać stale na zasobach IT, przez co obciążenie działów IT i analityki jest mniejsze i poprawia się czas uzyskania wartości.
W dzisiejszych czasach łatwiej jest znaleźć inżynierów danych, którzy znają Pythona i potrafią z pomocą tego języka utrzymać aplikację do przetwarzania danych Spark, niż tych, którzy potrafią to samo zrobić w Javie czy Scali. Wiele organizacji stopniowo przechodzi na Pythona dla wielu przypadków użycia, ze względu na większe szanse znalezienia pracowników, którzy “mówią” w tym języku.
Dla kontrastu mogę powiedzieć, że znam firmy, które desperacko potrzebują programistów Javy lub C# do utrzymania istniejących aplikacji, ale te języki są trudne (potrzeba lat, aby je opanować) i wydają się nieatrakcyjne dla nowych programistów, którzy mogą potencjalnie zarobić więcej na stanowiskach, które wykorzystują dużo łatwiejsze języki, takie jak Go czy Python.
Synergia pomiędzy ekspertami z różnych dziedzin
Jeśli Twoja firma korzysta z Pythona, istnieją duże szanse, że ten sam język może być używany przez użytkowników biznesowych, analityków danych, mistrzów danych, inżynierów danych, backend i web developerów, inżynierów DevOps, a nawet administratorów systemów. Prowadzi to do synergii w projektach, w których ludzie z różnych dziedzin mogą pracować wspólnie i korzystać z tych samych narzędzi.
Jakie są prawdziwe wąskie gardła w przetwarzaniu danych?
Na podstawie mojej własnej pracy, zwykle doświadczyłam wąskich gardeł nie w samym języku, ale raczej w zasobach zewnętrznych. Spójrzmy na kilka przykładów.
Zapisywanie do relacyjnych baz danych
Przetwarzając dane z narzędziem ETL, musimy na końcu załadować te dane do jakiegoś głównego miejsca. Podczas gdy moglibyśmy wykorzystać wielowątkowość w Pythonie, aby szybciej zapisywać dane do relacyjnej bazy (poprzez użycie większej liczby wątków), istnieje prawdopodobieństwo, że wzrost liczby równoległych zapisów mógłby maksymalnie wyczerpać możliwości CPU tej bazy.
Zdarzyło mi się to raz, gdy używałam wielowątkowości, aby przyspieszyć zapisy do bazy danych RDS Aurora na AWS. Następnie zauważyłam, że wykorzystanie CPU dla węzła wzrosło tak bardzo, że musiałam celowo spowolnić mój kod poprzez użycie mniejszej liczby wątków, aby upewnić się, że nie przerwę instancji bazy danych.
Oznacza to, że Python posiada mechanizmy paralelizacji i przyspieszania wielu operacji, ale Twoja relacyjna baza danych (ograniczona liczbą rdzeni procesora) ma swoje ograniczenia, które raczej nie zostaną rozwiązane poprzez użycie szybszego języka programowania.
Wykonywanie wywołań do zewnętrznych API
Praca z zewnętrznymi REST API, z których można wyodrębnić dane dla potrzeb analityki danych, to kolejny przykład, w którym sam język nie wydaje się być wąskim gardłem. Chociaż moglibyśmy przyspieszyć ekstrakcję danych poprzez wykorzystanie paralelizmu, mogłoby to pójść na marne, ponieważ wiele zewnętrznych API ogranicza liczbę żądań, które możemy wykonać w określonym czasie. Dlatego też często można spotkać się z celowym spowalnianiem skryptu, aby nie przekroczyć limitów żądań API:
time.sleep(10)
Praca z Big Data
Z mojego doświadczenia w pracy z dużymi zbiorami danych wynika, że nie można załadować naprawdę “dużych danych” do pamięci laptopa, niezależnie od tego, jakiego języka używasz. Dla takich przypadków użycia, prawdopodobnie będziesz musiał wykorzystać frameworki do przetwarzania rozproszonego, takie jak Dask, Spark, Ray, itp. Istnieje limit ilości danych, które można przetworzyć przy użyciu jednej instancji serwera lub laptopa.
Jeśli chcesz przenieść przetwarzanie danych do klastra węzłów obliczeniowych, być może nawet wykorzystując instancje GPU, które mogą jeszcze bardziej przyspieszyć obliczenia, Python posiada duży ekosystem frameworków, które ułatwiają to zadanie:
- Czy chcesz przyspieszyć wykonywanie obliczeń dla data science poprzez wykorzystanie procesorów graficznych? Użyj Pytorch, Tensorflow, Ray, lub Rapids (nawet z SQL — BlazingSQL)
- Czy chcesz przyspieszyć swój kod Pythona, aby przetwarzać Big Data? Użyj Spark (lub Databricks), Dask, lub Prefect (pod którego maską kryje się Dask)
- Czy chcesz przyspieszyć przetwarzanie danych na potrzeby analityki? Korzystaj z szybkich wyspecjalizowanych kolumnowych baz danych in-memory, które zapewniają szybkie przetwarzanie przy użyciu zapytań SQL.
A jeśli trzeba rozplanować i monitorować przetwarzanie danych, które odbywa się na klastrze węzłów obliczeniowych, to istnieje kilka platform do zarządzania przepływem pracy, napisanych w Pythonie, które przyspieszą development i usprawnią utrzymanie potoków danych, takich jak Apache Airflow, Prefect lub Dagster. Jeśli chcesz dowiedzieć się więcej na ten temat, zajrzyj do moich poprzednich artykułów.
A mówiąc na marginesie, to wydaje mi się, że niektórzy ludzie narzekający na Pythona nie wykorzystują go w pełni lub nie używają odpowiednich struktur danych dla danego problemu.
Podsumowując, jeśli potrzebujesz szybko przetwarzać duże ilości danych, prawdopodobnie będziesz potrzebował więcej zasobów obliczeniowych, a nie szybszego języka programowania. Istnieją biblioteki Pythona, które ułatwiają dystrybucję pracy na setki węzłów.
Wnioski
W tym artykule zastanawialiśmy się, czy Python jest prawdziwym wąskim gardłem w obecnym krajobrazie przetwarzania danych. Choć Python jest wolniejszy od wielu języków kompilowanych, to na pewno jest łatwy w stosowaniu i niezwykle różnorodny. Zauważyliśmy, że dla wielu osób ważniejsza jest praktyczność języka, która bije na głowę względy szybkości.
Na koniec powiedzieliśmy sobie, że — przynajmniej w inżynierii danych — wąskim gardłem niekoniecznie musi być sam język, ale raczej ograniczenia systemów zewnętrznych i sama ilość danych, która uniemożliwia ich przetwarzanie na pojedynczej maszynie, niezależnie od wybranego języka programowania.
Oryginał tekstu w języku angielskim przeczytasz tutaj.