>_ DevTrendsit

Lingua

Home

Linguaggi

Sezioni

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embedded Sicurezza
C-sharp

Ultra Profiler combina la raccolta di trace .NET di basso livello con l'interfaccia del Firefox Profiler

Ogni volta che le prestazioni calano o l'utilizzo della memoria aumenta in un'applicazione .NET, inizia la solita ricerca. PerfView ti spaventa con la sua interfaccia degli anni 2000, dotnet-trace produce report asciutti, e i profiler commerciali completi spesso si rivelano bestie pesanti. Recentemente, Alexander Mütel (conosciuto come xoofx, autore di Markdig e numerose altre utility C# di basso livello) ha rilasciato il suo strumento Ultra, che cerca di combinare la raccolta dettagliata di trace con un'interfaccia web comoda.

Lo strumento raccoglie campioni di basso livello fino al kernel del sistema operativo e visualizza i risultati tramite profiler.firefox.com. Il risultato è uno strumento da riga di comando leggero che genera trace di poche centinaia di kilobyte e apre immediatamente una visualizzazione chiara con timeline, flamegraph e call tree.

Screenshot trace di Ultra

Cosa c'è sotto il cofano e come funziona

L'idea principale dietro il progetto è evitare di inventare una propria UI ingombrante. L'autore ha preso il motore del Firefox Profiler, eccellente nei grafici interattivi, e ha scritto un raccoglitore di dati efficiente per .NET.

La raccolta viene gestita in modo diverso su piattaforme diverse:

  • Su Windows, il profiling si basa su ETW (Event Tracing for Windows). La frequenza di campionamento qui può raggiungere fino a 8190 campioni al secondo. Questo ti dà uno stack di chiamate onesto: puoi vedere non solo il codice .NET gestito, ma anche le chiamate del runtime CLR, le chiamate alle librerie native e le funzioni del kernel Windows.
  • Su macOS, il raccoglitore funziona attraverso l'iniezione di una libreria dinamica direttamente nel processo all'avvio e ascolta EventPipe. Qui la frequenza è limitata a 1000 campioni al secondo, e il trace cattura le chiamate nello spazio utente gestite e native.

Nel report, tutte le chiamate sono organizzate in categorie distinte: .NET, .NET JIT, .NET GC, .NET CLR, Native e Kernel. È immediatamente chiaro se il processo sta girando in un ciclo, aspettando un blocco nel kernel, o bloccato sulla compilazione di un metodo.

Dettagli sul Garbage Collector e JIT

Oltre ai campioni CPU, l'utility allega eventi runtime.

I marcatori di compilazione JIT con nomi di metodo specifici appaiono nella timeline, quindi la fase di warmup dell'applicazione è chiaramente visibile. Per il GC, il trace registra le statistiche dell'heap, gli eventi di pausa del runtime (GCSuspendEE e GCRestartEE) e le allocazioni di memoria.

I trace sono compatti: un'esecuzione di dieci secondi di solito pesa solo pochi megabyte. Il file risultante può essere condiviso con un collega o caricato direttamente su share.firefox.dev per l'analisi collaborativa degli incidenti.

Avvio rapido

L'utility viene distribuita come uno strumento globale standard. Richiede .NET SDK 10 o superiore:

dotnet tool install -g Ultra

Su Windows, sono necessari diritti amministrativi per raccogliere gli stack del kernel. Puoi profilare un programma separato usando il separatore di argomenti --:

ultra.exe profile -- my_command.exe arg0 arg1

Se un servizio è già in esecuzione su un server o sulla macchina locale, basta passare l'ID del processo:

ultra.exe profile 15243

Dopo che la raccolta termina con Ctrl+C, l'utility salva il file di trace.

Su macOS con chip Apple Silicon, non sono necessari privilegi elevati, ma c'è un'avvertenza. Il profiler funziona solo all'avvio di un nuovo binario:

ultra profile -- ./my_command arg0 arg1

L'attacco per PID su Mac non è ancora possibile, perché il raccoglitore inietta esclusivamente all'avvio del processo. La raccolta degli stack del kernel su macOS non è supportata nemmeno, e i simboli delle librerie di sistema nella cache condivisa dyld rimangono irrisolti.

Integrazione con i modelli linguistici

Un dettaglio interessante: l'ecosistema del progetto ha già un server MCP separato chiamato UltraMCP di Kirill Osenkov. Collega i risultati del profiling direttamente agli agenti AI come Cursor o Claude Desktop. Un agente può leggere il trace stesso, trovare i colli di bottiglia nel codice e suggerire correzioni di ottimizzazione senza dover copiare manualmente gli stack trace in una chat.

Vale la pena provarlo

Lo strumento è recente, con una licenza BSD-2-Clause aperta. Su macOS ci sono ancora limitazioni funzionali, ma per Windows è già un'ottima alternativa agli strumenti pesanti.

Se hai regolarmente bisogno di capire perché un servizio è lento ad avviarsi, dove va la memoria in un ciclo stretto, o quanto tempo richiede il JIT, aggiungi Ultra al tuo toolkit. La rapida raccolta di trace con un singolo comando senza dover configurare nulla fa risparmiare un sacco di tempo.

Progetti correlati