Głównym celem każdej aplikacji jest zapewnienie satysfakcji użytkownikom.
Aby osiągnąć ten cel, aplikacja musi być szybka, elastyczna, łatwa w obsłudze i niezawodna, a także posiadać szereg innych pożądanych cech.
Utrzymanie oprogramowania w stanie zapewniającym optymalną wydajność jest jednak zadaniem złożonym.
Gdy kod zaczyna wykonywać niepotrzebne operacje, wpada w pętle błędów i napotyka dodatkowe problemy, prowadzi to do spadku efektywności. Aplikacja może zwolnić, przestać odpowiadać lub działać nieprawidłowo.
Jeśli te kwestie nie zostaną rozwiązane, ogólna wydajność aplikacji ulegnie pogorszeniu.
W efekcie użytkownicy mogą odczuwać frustrację lub całkowicie zrezygnować z aplikacji z powodu słabej wydajności i niskiej szybkości działania. Ma to negatywny wpływ na reputację firmy oraz generuje straty finansowe. Dlatego istotne jest analizowanie, przeglądanie i debugowanie kodu w celu uzyskania optymalnej wydajności. Efektywnym sposobem na osiągnięcie tego celu jest wykorzystanie narzędzi do profilowania oprogramowania, które pomagają w monitorowaniu i debugowaniu kodu oraz identyfikacji i eliminacji wąskich gardeł.
W niniejszym artykule omówimy koncepcję profilowania oprogramowania oraz przedstawimy, w jaki sposób może ono pomóc w optymalizacji aplikacji. Następnie zaprezentujemy kilka najlepszych narzędzi do profilowania, które można wykorzystać do debugowania aplikacji i poprawy jej wydajności.
Czym jest profilowanie oprogramowania?
Profilowanie oprogramowania to dynamiczna analiza kodu, w której zachowanie programu jest badane na podstawie danych gromadzonych w trakcie jego działania. Głównym celem profilowania jest zidentyfikowanie tych fragmentów kodu, które wymagają optymalizacji w celu zwiększenia szybkości działania aplikacji, poprawy jej responsywności oraz zmniejszenia zużycia pamięci i innych zasobów.
Narzędzia do profilowania oprogramowania zazwyczaj mierzą czas wykonywania i częstotliwość wywołań funkcji, a także analizują zużycie pamięci oraz złożoność czasową programu. Istnieją również specjalistyczne profilery, takie jak profilery pamięci.
Profilowanie najczęściej realizuje się poprzez instrumentację kodu źródłowego programu. Profilery wykorzystują różne techniki, takie jak metody instrumentalne, oparte na zdarzeniach, statystyczne lub symulacyjne.
Dlaczego profilowanie oprogramowania jest istotne?
Profilowanie oprogramowania jest niezbędne do określenia zużycia zasobów i czasu wykonywania poszczególnych funkcji. Pomaga zoptymalizować szybkość działania programu, jednocześnie zapewniając minimalne wykorzystanie zasobów.
Dodatkowo, profilowanie umożliwia monitorowanie i optymalizację wykorzystania procesora oraz czasu wykonywania instrukcji.
Wybór odpowiedniego narzędzia do profilowania oprogramowania jest kluczowy, aby przyspieszyć debugowanie problemów z wydajnością, poprawić działanie aplikacji i zapewnić lepsze wrażenia użytkownikom. Wiele profilerów oferuje szczegółowe raporty oraz interaktywne wykresy i wizualizacje, które pomagają zidentyfikować przyczynę problemów, co ułatwia ich rozwiązanie.
Poniżej znajduje się lista polecanych narzędzi do profilowania oprogramowania, które warto wypróbować. Podziel się z nami swoimi doświadczeniami i powiedz, które z nich sprawdziły się u Ciebie najlepiej.
py-spy
py-spy to doskonały profiler próbkujący dla języka Python. Umożliwia on monitorowanie wszystkich działań wykonywanych przez aplikację napisaną w Pythonie.
W tym celu nie ma potrzeby modyfikowania kodu ani ponownego uruchamiania programu. py-spy charakteryzuje się niskim narzutem i jest zaimplementowany w języku Rust, co zapewnia jego wysoką wydajność. Narzędzie działa niezależnie od profilowanej aplikacji Python, dzięki czemu jest bezpieczne w użyciu w środowisku produkcyjnym.
Narzędzie pozwala na rejestrowanie profili, generowanie wykresów płomieniowych w postaci interaktywnych plików SVG. Użytkownik może również skorzystać z dodatkowych opcji, takich jak zmiana częstotliwości próbkowania, profilowanie rozszerzeń C, podprocesów oraz identyfikatorów wątków. Dostępny jest również podgląd na żywo funkcji wykonywanych w programie za pomocą polecenia „top”, a także możliwość wyświetlenia aktualnego stosu wywołań za pomocą polecenia „dump” dla każdego wątku Pythona.
Narzędzie obsługuje wszystkie wersje interpretera CPython, w tym od 2.3 do 2.7 oraz od 3.3 do 3.8. py-spy można zainstalować z PyPI lub z repozytorium GitHub.
Pyroscope
Pyroscope, oprogramowanie do ciągłego profilowania o otwartym kodzie źródłowym, Pyroscope umożliwia debugowanie problemów z wydajnością aplikacji w ciągu kilku minut.
W celu jego użycia wystarczy uruchomić serwer i agenta. Bez względu na wykorzystywane narzędzia (Docker, Linux, Ruby, Go), Pyroscope jest kompatybilny. System pamięci masowej Pyroscope umożliwia szybkie wykonywanie zapytań, niezależnie od zakresu analizowanych danych (od kilku sekund do kilku miesięcy).
Narzędzie wykorzystuje technikę profilowania próbkowego, która minimalizuje wpływ na wydajność aplikacji. Pyroscope efektywnie przechowuje dane profilowania, co sprawia, że jest opłacalnym rozwiązaniem, nawet przy przechowywaniu danych z różnych aplikacji przez długi czas.
Pyroscope działa na systemach macOS, Linux i Docker oraz obsługuje programy napisane w językach Python, Go i Ruby.
Bubbleprof
Bubbleprof od Clinic.js oferuje unikalny sposób profilowania oprogramowania napisanego w Node.js. Narzędzie wykorzystuje interfejs użytkownika „bąbelkowy”, który pozwala zarówno ekspertom, jak i początkującym użytkownikom na określenie asynchronicznego czasu spędzonego w aplikacji.
Bubbleprof wizualizuje działanie procesów Node.js, analizując jego asynchroniczne operacje, grupując je, obliczając opóźnienia i mapując je.
Bubbleprof mierzy czasy operacji, analizując rozmiar „bąbelków” w danej grupie operacji, która może obejmować kod użytkownika, rdzeń węzła lub moduł. Narzędzie łączy również sąsiednie grupy, aby zmniejszyć złożoność wizualizacji.
Opóźnienia w przepływie operacji z jednej grupy do drugiej są mierzone na podstawie długości strzałek łączących „bąbelki”. Dodatkowo, w celu odzwierciedlenia różnych etapów procesu, Bubbleprof stosuje różne kolory. Kolorowe linie wewnętrzne obrazują również mieszankę typów asynchronicznych operacji, które mogą być przyczyną opóźnień.
Pyinstrument
Zoptymalizuj kod Pythona za pomocą Pyinstrument.
Narzędzie to pokazuje, dlaczego kod Pythona działa wolno i pomaga zdiagnozować problemy, co umożliwia uzyskanie optymalnej wydajności.
Aby skorzystać z Pyinstrument, nie trzeba pisać skryptu w Pythonie; wystarczy wywołać go bezpośrednio z wiersza poleceń. Skrypt działa tak jak zwykle, a narzędzie wyświetla kolorowe podsumowanie obszarów, w których aplikacja spędzała najwięcej czasu. Pyinstrument oferuje również API w języku Python, co dodatkowo upraszcza proces profilowania.
Pyinstrument umożliwia również profilowanie żądań sieciowych w Flask i Django, dla których dostępne jest szczegółowe opracowanie. Warto zaznaczyć, że Pyinstrument wykorzystuje profilowanie statystyczne, które rejestruje stos wywołań co 1 ms, zamiast śledzenia każdego wywołania funkcji wykonanego przez program.
Jest to korzystne, ponieważ profilery statystyczne charakteryzują się mniejszym narzutem w porównaniu z profilerami śledzącymi. Ponieważ Pyinstrument rejestruje cały stos, śledzenie kosztownych wywołań funkcji staje się łatwe. Ponadto narzędzie ukrywa domyślnie ramki bibliotek, pozwalając skupić się na aplikacjach lub modułach, które mają największy wpływ na wydajność.
Debugowanie problemów z wydajnością jest ułatwione, ponieważ Pyinstrument rejestruje czas spędzony przy użyciu „zegara ściennego”. Narzędzie śledzi cały czas działania programu, w tym operacje odczytu plików, pobierania danych, komunikacji z bazą danych itp.
Xdebug
Aby poprawić wydajność kodu i uczynić programowanie przyjemniejszym, Xdebug oferuje szerokie możliwości profilowania i debugowania.
Xdebug jest rozszerzeniem PHP, które pozwala na identyfikację wąskich gardeł w aplikacji PHP i analizę jej wydajności za pomocą zewnętrznych narzędzi wizualizacyjnych generujących wykresy.
Xdebug tworzy szczegółowe dane wyjściowe, które pokazują ścieżkę aplikacji prowadzącą do wystąpienia błędu, w tym parametry przekazywane do poszczególnych funkcji. Narzędzie to służy do śledzenia błędów. Aby pomóc programistom w zrozumieniu działania aplikacji, Xdebug generuje informacje oznaczone kolorami oraz prezentuje widoki strukturalne.
Xdebug oferuje również zdalny debugger, który można wykorzystać do połączenia z uruchomionym kodem, IDE lub przeglądarką, co umożliwia ustawianie punktów przerwania i wykonywanie kodu linia po linii. Dodatkową funkcją jest analiza pokrycia kodu, która pokazuje, jaka część kodu programu została wykonana i pomaga w testach jednostkowych.
SPX
Proste rozszerzenie profilowania (SPX) jest przeznaczone dla języka PHP. Posiada kilka unikalnych cech, które odróżniają go od innych rozszerzeń profilujących. Jest całkowicie bezpłatne w użyciu i ograniczone jedynie do infrastruktury użytkownika, co oznacza brak ryzyka wycieku danych.
Prostota SPX sprawia, że jest bardzo łatwe w użyciu: wystarczy ustawić zmienną środowiskową lub wiersz poleceń, aby profilować skrypt. Można również włączyć przycisk radiowy na stronie internetowej, aby profilować skrypt. W efekcie nie ma potrzeby ręcznego instrumentowania kodu.
SPX obsługuje również skrypty uruchamiane z wiersza poleceń, z możliwością przerwania procesu za pomocą Ctrl-C. Eliminuje to potrzebę korzystania z dodatkowego programu uruchamiającego z wiersza poleceń lub dedykowanego rozszerzenia przeglądarki. SPX obsługuje wiele metryk (około 22), w tym różne metryki czasu i pamięci, obiektów, używanych plików, wejścia/wyjścia itd.
SPX może gromadzić dane bez opuszczania kontekstu. Interfejs internetowy umożliwia konfigurację i włączanie profilowania dla bieżącej sesji przeglądarki oraz wyświetla listę wszystkich szczegółów profilowanych skryptów i raportów. Interfejs internetowy pozwala wybrać konkretny raport do dalszej analizy i zawiera interaktywne wizualizacje, takie jak Flamegraph, płaski profil oraz oś czasu, które można skalować do milionów wywołań funkcji.
Prefix
Prefix od Stackify to łatwy w instalacji i lekki program do profilowania kodu, ceniony przez wielu programistów. Pomaga on wyeliminować wąskie gardła w wydajności aplikacji, zoptymalizować ją i poprawić komfort użytkownika.
Rozbudowane możliwości śledzenia i profilowania Prefix umożliwiają szybkie znajdowanie ukrytych wyjątków, wolnych zapytań SQL i innych problemów. Narzędzie zapewnia programistom rzeczywistą moc APM (monitorowania wydajności aplikacji). Prefix weryfikuje wydajność kodu podczas jego pisania i pozwala na wdrażanie kodu o wyższej wydajności do testowania.
Dzięki temu ilość zgłoszeń do pomocy technicznej ze strony produkcyjnej jest mniejsza, a menedżerowie ds. rozwoju mogą szybciej osiągać wyznaczone cele. Prefix pozwala zidentyfikować wszystkie zapytania o niskiej wydajności, nieznane wąskie gardła i zapytania generowane przez ORM.
Można również śledzić każdy parametr wywołania SQL, pobierać pomiary czasu i przeglądać rekordy, których dotyczy problem. Prefix ułatwia także wykrywanie wzorców N+1. Narzędzie eliminuje konieczność ręcznego analizowania nieuporządkowanych dzienników poprzez łączenie ich w łatwe do analizy struktury.
Prefix umożliwia bezpośrednie znalezienie kontekstu podejrzanego wpisu w dzienniku w żądaniu zapytania i przejście z jednego dziennika do śladu w celu bezproblemowego debugowania. Prefix uwidacznia słabo działające zależności, co jest pomocne w znajdowaniu ukrytych wyjątków i pracy ze starszymi sekcjami kodu lub strukturami. Zależności te mogą obejmować usługi internetowe, usługi innych firm, usługi pamięci podręcznej i inne.
Prefix działa na systemach Windows i Mac oraz obsługuje platformy .Net, Ruby, Java, PHP, Python i Node.js.
Scalene
Scalene to wysoce precyzyjny i wydajny profiler GPU, CPU i pamięci dla programów napisanych w Pythonie. Oferuje kilka zalet w porównaniu z innymi profilerami, takich jak obsługa większych obciążeń i dostarczanie bardziej szczegółowych informacji.
Scalene jest bardzo szybki i wykorzystuje próbkowanie zamiast instrumentacji. Nie opiera się na funkcjach śledzenia Pythona. Ponadto jego narzut wynosi zazwyczaj poniżej 10-20%. Narzędzie wykonuje profilowanie oprogramowania na poziomie linii kodu i wskazuje te linie, które odpowiadają za czas wykonywania programu.
Szczegółowość danych dostarczanych przez Scalene jest bardziej wartościowa niż w przypadku profilowania na poziomie funkcji. Narzędzie oddziela czas spędzony w kodzie Pythona od czasu spędzonego w kodzie natywnym, takim jak biblioteki. Ponieważ większość programistów Pythona nie optymalizuje wydajności kodu natywnego, mogą oni skupić się na optymalizacji kodu, który można poprawić.
Scalene podświetla „hotspoty” na czerwono, co ułatwia identyfikację miejsc, gdzie występuje największe zużycie procesora/przydział pamięci, oraz pozwala na łatwe oddzielenie czasu systemowego w celu znalezienia problemów z operacjami wejścia/wyjścia. Scalene raportuje czas działania GPU, profiluje zużycie pamięci i śledzi wykorzystanie procesora. Scalene może również identyfikować potencjalne wycieki pamięci, analizować objętość kopiowanych danych oraz generować zredukowane profile dla linii kodu, które zużywają więcej niż 1% procesora.
VisualVM
Uniwersalne narzędzie do rozwiązywania problemów z Javą, VisualVM, jest przeznaczone do stosowania zarówno w fazie produkcji, jak i rozwoju. Jest to wizualne oprogramowanie, które integruje lekkie funkcje profilowania i narzędzia JDK wiersza poleceń.
VisualVM monitoruje aplikacje działające w Javie 1.4+ i rozwiązuje problemy z nimi przy użyciu kilku technologii, takich jak JMX, jvmstat, Attach API i Serviceability Agent. Narzędzie to jest idealne dla inżynierów jakości, administratorów systemów i użytkowników końcowych.
VisualVM automatycznie wykrywa zdalnie i lokalnie uruchomione aplikacje oparte na Javie i wyświetla je. Narzędzie pozwala również na ręczne definiowanie programów za pomocą połączenia JMX. Dla każdego procesu wyświetlane są typowe dane, takie jak PID, argumenty, ścieżka JDK, klasa główna, flagi JVM, wersja JVM oraz właściwości systemu.
VisualVM monitoruje wykorzystanie procesora, sterty, metaprzestrzeni, pamięci stałej generacji, uruchomionych wątków i załadowanych klas w aplikacji. Wyświetla wszystkie uruchomione wątki na osi czasu, wraz z zagregowanym czasem uśpienia, działania, parkowania, monitorowania i oczekiwania.
VisualVM umożliwia wykonywanie profilowania z instrumentacją lub próbkowaniem w celu zarządzania pamięcią i wydajnością aplikacji. Wyświetla zrzuty wątków, zapewniając szybki wgląd w procesy. Narzędzie tworzy również migawki .hprof na żądanie, co pomaga wykryć nieefektywne wykorzystanie sterty i debugować wycieki pamięci.
VisualVM może również odczytywać podstawowe dane dotyczące uszkodzonego procesu opartego na Javie, wraz z jego środowiskiem. Umożliwia analizowanie aplikacji w trybie offline; zapisuje środowisko uruchomieniowe aplikacji i konfigurację, wykonane zrzuty sterty, zrzuty wątków i migawki profilowania, które można przetwarzać w trybie offline.
Narzędzie działa w systemach Windows, Linux i Unix.
Orbit Profiler
Wizualizuj aplikację C/C++ i szybko znajdź problemy z wydajnością dzięki narzędziu Orbit Profiler. Jest to narzędzie do debugowania i samodzielny profiler, którego celem jest pomoc programistom w analizowaniu i zrozumieniu przepływu wykonania złożonej aplikacji.
Orbit Profiler zapewnia szczegółowy wgląd we wszystko, co dzieje się w aplikacji, co pozwala na szybkie wyeliminowanie wąskich gardeł wydajności i przywrócenie wysokiej sprawności aplikacji.
Orbit Profiler może efektywnie pracować z dowolną aplikacją C lub C++, pod warunkiem dostępu do pliku PDB. Narzędzie rozpoczyna profilowanie po zakończeniu pobierania programu. Przechodzi do docelowego procesu, podłącza się do wybranych funkcji i wykonuje profilowanie.
Orbit Profiler może działać nawet na zoptymalizowanych kompilacjach końcowych lub wysyłkowych. Oprócz dynamicznej instrumentacji, Orbit Profiler oferuje również możliwość próbkowania „zawsze włączonego”, które jest szybkie, dostępne i niezawodne.
Orbit Profiler działa w systemach Windows i Linux.
Uber JVM Profiler
Wyposażony w zaawansowane możliwości profilowania, Uber JVM Profiler jest kolejnym dobrym rozwiązaniem dla aplikacji opartych na Javie.
Oferuje agenta Java, który zbiera różne ślady stosu i metryki dla procesów Spark/Hadoop JVM w sposób rozproszony, takie jak metryki pamięci/CPU/IO.
Narzędzie może śledzić argumenty i metody Java w kodzie użytkownika bez konieczności jego modyfikacji. Uber JVM Profiler umożliwia śledzenie opóźnień wywołań węzłów nazw systemu plików HDFS dla każdej aplikacji Spark i identyfikację problemów. Może również śledzić ścieżki plików HDFS aplikacji Spark, co pozwala znaleźć „gorące” pliki i przeprowadzić dalszą optymalizację.
Uber JVM Profiler został pierwotnie stworzony do profilowania aplikacji Spark, które zazwyczaj obejmują wiele maszyn lub procesów dla jednej aplikacji. Dzięki temu łatwo jest korelować metryki dla tych maszyn lub procesów.
Jednak narzędzie działa jak typowy agent Java i może być używane w dowolnym procesie JVM. Jego funkcje obejmują:
- Debugowanie wykorzystania pamięci przez moduły wykonawcze aplikacji Spark, takie jak pamięć sterty Java, pamięć natywna, pamięć bez sterty, pula buforów i pula pamięci
- Debugowanie wykorzystania procesora i czasu zbierania śmieci
- Debugowanie metod klasy Java pod kątem ich częstotliwości i czasu trwania
- Profilowanie argumentów (debugowanie i śledzenie wywołania metody klasy java i jej wartości argumentu)
- Profilowanie stosu i generowanie wykresów płomieniowych dla czasu procesora
- Debugowanie metryk we/wy i metryk wątków JVM
Tracy
Tracy to przydatne narzędzie, które ułatwia programistom debugowanie programów PHP. Charakteryzuje się przyjaznym designem i zaawansowanymi funkcjami, takimi jak obsługa CLI, debugowanie wywołań AJAX i wiele innych.
Tracy pozwala na szybkie identyfikowanie i poprawianie błędów, zrzucanie zmiennych, rejestrowanie błędów, wizualizację zużycia pamięci oraz określanie czasu wykonania zapytań lub skryptów. Używanie kolorów i wyróżnianie problemów na czerwono oraz dodawanie jasnych opisów ułatwia wizualizację wyjątków i błędów oraz ich zrozumienie.
Tracy posiada funkcję rejestrowania i automatycznego wykrywania środowiska. Przechowuje dane w plikach dziennika i wyświetla komunikaty o błędach serwera odwiedzającym podczas przestojów. Tracy można zintegrować z Drupal 7, OpenCart, WordPress i innymi platformami.
vprof
vprof to wizualny profiler dla aplikacji Pythona. Dostarcza interaktywnych wizualizacji różnych aspektów działania programu, takich jak wykorzystanie pamięci i czas działania.
Narzędzie jest dostępne na licencji BSD i obsługuje język Python 3.4 i nowsze.
Podsumowanie
Wydajność aplikacji jest kluczowym czynnikiem wpływającym na zadowolenie użytkowników. W przypadku wystąpienia problemów z wydajnością należy być przygotowanym na szybką diagnozę problemu, zanim zacznie on negatywnie wpływać na doświadczenie użytkownika.
Optymalizuj swoje aplikacje i natychmiast rozwiązuj problemy, aby zapewnić użytkownikom szybką i niezawodną wydajność aplikacji, wykorzystując narzędzia opisane w tym artykule.
Poniżej znajduje się krótka tabela porównawcza prezentująca wymienione narzędzia profilujące oraz ich główne zastosowania.
Nazwa
Języki
py-spy
Python
Pyroscope
Python, Ruby, Go
Bubbleprof
Node.js
Pyinstrument
Python
Xdebug
PHP
SPX
PHP
Prefix
Python, .NET, Java, Node.js, Ruby, PHP
Scalene
Python
VisualVM
Java
Orbit Profiler
C, C++
Uber JVM Profiler
Java
Tracy
PHP
vprof
Python