>_ DevTrendspl

Język

Strona główna

Języki

Sekcje

Frontend Backend Mobilne DevOps AI / ML GameDev Blockchain Systemy wbudowane Bezpieczeństwo
C-sharp

Ultra Profiler łączy niskopoziomowe zbieranie śladów .NET z interfejsem Firefox Profilera

Za każdym razem, gdy wydajność spada lub zużycie pamięci gwałtownie rośnie w aplikacji .NET, rozpoczyna się znajome poszukiwanie. PerfView przeraża swoim interfejsem z wczesnych lat 2000, dotnet-trace wypluwa suche raporty, a pełnoprawne komercyjne profilery często okazują się ciężkimi bestiami. Niedawno Alexander Mütel (znany jako xoofx, autor Markdig i wielu innych niskopoziomowych narzędzi C#) wydał swoje narzędzie Ultra, które próbuje połączyć szczegółowe zbieranie śladów z wygodnym interfejsem webowym.

Narzędzie zbiera niskopoziomowe próbki aż do jądra systemu operacyjnego i wyświetla wyniki przez profiler.firefox.com. Efektem jest lekkie narzędzie wiersza poleceń, które generuje ślady ważące zaledwie kilka megabajtów i natychmiast otwiera czytelną wizualizację z osiami czasu, wykresami płomieniowymi i drzewami wywołań.

Zrzut ekranu śladu Ultra

Co siedzi pod maską i jak to działa

Główna idea projektu polega na unikaniu tworzenia własnego, rozbudowanego interfejsu użytkownika. Autor wykorzystał silnik Firefox Profilera, który doskonale radzi sobie z wykresami interaktywnymi, i napisał wydajny kolektor danych dla .NET.

Zbieranie danych odbywa się inaczej na różnych platformach:

  • Na Windows profilowanie opiera się na ETW (Event Tracing for Windows). Częstotliwość próbkowania może sięgać nawet 8190 próbek na sekundę. Daje to uczciwy stos wywołań: widać nie tylko zarządzany kod .NET, ale także wywołania środowiska uruchomieniowego CLR, wywołania natywnych bibliotek i funkcje jądra Windows.
  • Na macOS kolektor działa poprzez wstrzyknięcie dynamicznej biblioteki bezpośrednio do procesu przy uruchomieniu i nasłuchuje EventPipe. Tutaj częstotliwość jest ograniczona do 1000 próbek na sekundę, a ślad obejmuje wywołania zarządzane i natywne w przestrzeni użytkownika.

W raporcie wszystkie wywołania są starannie podświetlone i zorganizowane według kategorii: .NET, .NET JIT, .NET GC, .NET CLR, Native i Kernel. Natychmiast widać, czy proces kręci się w pętli, czeka na blokadę wątku w jądrze, czy utknął przy kompilacji metody.

Szczegóły o garbage collectorze i JIT

Oprócz próbek CPU narzędzie dołącza zdarzenia środowiska uruchomieniowego.

Znaczniki kompilacji JIT z określonymi nazwami metod pojawiają się na osi czasu, dzięki czemu faza rozgrzewki aplikacji jest wyraźnie widoczna. Dla GC ślad rejestruje statystyki sterty, zdarzenia pauzy środowiska uruchomieniowego (GCSuspendEE i GCRestartEE) oraz alokacje pamięci.

Ślady są kompaktowe: dziesięciosekundowe uruchomienie zwykle waży zaledwie kilka megabajtów. Wynikowy plik można udostępnić koledze lub przesłać bezpośrednio na share.firefox.dev w celu wspólnej analizy incydentów.

Szybki start

Narzędzie jest dystrybuowane jako standardowe narzędzie globalne. Wymaga .NET SDK 10 lub nowszego:

dotnet tool install -g Ultra

Na Windows wymagane są prawa administratora do zbierania stosów jądra. Można profilować osobny program używając separatora argumentów --:

ultra.exe profile -- my_command.exe arg0 arg1

Jeśli usługa jest już uruchomiona na serwerze lub maszynie lokalnej, wystarczy przekazać identyfikator procesu:

ultra.exe profile 15243

Po zakończeniu zbierania Ctrl+C narzędzie zapisuje plik śladu.

Na macOS z układami Apple Silicon podwyższone uprawnienia nie są wymagane, ale jest zastrzeżenie. Profiler działa tylko przy uruchamianiu nowego pliku binarnego:

ultra profile -- ./my_command arg0 arg1

Dołączanie przez PID na Mac nie jest jeszcze możliwe, ponieważ kolektor wstrzykuje się wyłącznie przy starcie procesu. Zbieranie stosów jądra na macOS również nie jest obsługiwane, a symbole z bibliotek systemowych w dyld shared cache pozostają nierozwiązane.

Integracja z modelami językowymi

Ciekawe szczegóły: ekosystem projektu ma już osobny serwer MCP o nazwie UltraMCP autorstwa Kirilla Osenkova. Łączy on wyniki profilowania bezpośrednio z agentami AI, takimi jak Cursor czy Claude Desktop. Agent może samodzielnie odczytać ślad, znaleźć wąskie gardła w kodzie i zasugerować poprawki optymalizacyjne bez ręcznego kopiowania stosów wywołań do czatu.

Czy warto wypróbować

Narzędzie jest świeże, z otwartą licencją BSD-2-Clause. Na macOS wciąż występują ograniczenia funkcjonalne, ale dla Windows to już świetna alternatywa dla ciężkich narzędzi.

Jeśli regularnie musisz sprawdzać, dlaczego usługa wolno się uruchamia, gdzie trafia pamięć w ciasnej pętli lub ile czasu zajmuje JIT, dodaj Ultra do swojego zestawu narzędzi. Szybkie zbieranie śladów jednym poleceniem bez grzebania w konfiguracji oszczędza masę czasu.

Powiązane projekty