Condividi tramite


Profilare l'app con GitHub Copilot Profiler Agent

L'Agente Profiler di Copilot di GitHub opera insieme a GitHub Copilot e guida nei test e nei miglioramenti delle prestazioni.

Questa esercitazione illustra come profilare le applicazioni e migliorare le prestazioni usando l'agente di Copilot Profiler.

L'agente profiler può eseguire tutte le attività seguenti.

  • Analizzare l'utilizzo della CPU, le allocazioni di memoria e il comportamento di runtime.
  • Colli di bottiglia delle prestazioni della superficie.
  • Generare benchmarkDotNet o ottimizzare i benchmark BenchmarkDotNet esistenti.
  • Applicare le ottimizzazioni suggerite.
  • Convalidare i miglioramenti in un ciclo guidato.

L'agente profiler è particolarmente utile quando:

  • Non si ha familiarità con la profilatura.
  • Non si è certi di dove iniziare con l'ottimizzazione delle prestazioni.
  • Si vogliono convalidare le ottimizzazioni con benchmark reali.
  • Si stanno lavorando ad app ad alte prestazioni, ad esempio giochi, servizi o strumenti client.

Per informazioni su altre funzionalità di profilatura in Copilot, vedere Scenari avanzati dell'intelligenza artificiale. Per informazioni generali sugli agenti Copilot e sulla modalità agente, vedere Usare la modalità agente Copilot.

Prerequisiti

Per iniziare, è necessario:

Avviare una sessione di profilatura

  1. In Visual Studio creare una nuova app console C#.

    Nella finestra iniziale scegliere Crea un nuovo progetto. Digitare console nella casella di ricerca, selezionare C# come linguaggio e quindi scegliere App console per .NET. Scegliere Avanti. Digitare un nome di progetto come ConsoleApp_CopilotProfile e selezionare Avanti. Scegliere un framework di destinazione ( ad esempio .NET 8) e scegliere Crea.

  2. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo Dipendenze nel progetto, scegliere Gestisci pacchetti NuGet, cercare EntityFramework e quindi aggiungere i pacchetti seguenti al progetto:

    • Microsoft.EntityFramework.Core
    • Microsoft.EntityFramework.Core.InMemory

    L'app usa un database in memoria per semplificare la configurazione del progetto.

  3. Sostituire il codice in Program.cs con il codice seguente:

    using System.Diagnostics;
    using Microsoft.EntityFrameworkCore;
    
    // Configure EF Core to use the InMemory provider
    var options = new DbContextOptionsBuilder<AppDbContext>()
        .UseInMemoryDatabase("PerfDemoDb")
        .Options;
    
    using var db = new AppDbContext(options);
    
    // Seed 100,000 records once
    if (!db.People.Any())
    {
        var rand = new Random(42);
        var cities = new[]
        {
            "Chicago", "Seattle", "Cairo", "London", "Paris",
            "Cleveland", "Calgary", "Dallas", "Berlin", "Copenhagen"
        };
    
        var people = Enumerable.Range(1, 100_000).Select(i => new Person
        {
            Name = $"Person {i}",
            Age = rand.Next(18, 80),
            City = cities[rand.Next(cities.Length)]
        });
    
        db.People.AddRange(people);
        db.SaveChanges();
    }
    
    Console.WriteLine($"Seeded records: {db.People.Count():N0}");
    
    // Inefficient LINQ pattern: materialize everything and repeatedly re-materialize + chain ToList
    // This simulates client-heavy work that doesn't scale, even with in-memory provider
    var sw = Stopwatch.StartNew();
    
    // Full materialization of all rows
    var all = db.People.ToList();
    
    // Extra ToList calls create multiple large intermediate lists
    var inefficient = all
        .Where(p => p.Age > 50)
        .ToList()
        .Where(p => p.City.StartsWith("C"))
        .ToList()
        .Select(p => p.Name)
        .Distinct()
        .OrderBy(n => n)
        .Take(10)
        .ToList();
    
    sw.Stop();
    Console.WriteLine($"Inefficient query returned {inefficient.Count} rows in {sw.ElapsedMilliseconds} ms");
    
    // EF Core entity
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public int Age { get; set; }
        public string City { get; set; } = string.Empty;
    }
    
    // EF Core DbContext
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
        public DbSet<Person> People => Set<Person>();
    }
    
  4. Selezionare Compila > soluzione per assicurarsi che l'app venga compilata senza errori.

Chiedere a Copilot informazioni dettagliate sulla profilatura

  1. Aprire la finestra Chat di Copilot e usare il prompt seguente.

    @Profiler Please evaluate the performance of this code

  2. Seleziona Invia.

    Il @Profiler comando chiama l'agente di Copilot Profiler.

    Screenshot della chiamata dell'agente del profiler.

    In alternativa, è possibile avviare l'agente del profiler scegliendo manualmente Seleziona strumenti e abilitando manualmente l'agente profiler e quindi passando alla modalità agente. Con questo metodo non è necessario usare il @Profiler comando .

    Copilot chiede se si vuole eseguire il profiler.

    Screenshot della richiesta di avvio della profilatura.

  3. Scegliere Conferma.

    L'agente esegue una serie di passaggi in modo indipendente. Esamina il codice, aggiunge il supporto al progetto per BenchmarkDotNet, inclusi riferimenti e pacchetti del progetto, aggiunge benchmark a un nuovo file ed esegue test di confronto rispetto al nuovo codice generato.

    I risultati del benchmark vengono visualizzati nella finestra Output, con l'output impostato su Hub di diagnostica.

    Screenshot dell'output del benchmark.

    I risultati della sessione di diagnostica vengono visualizzati in un report di file con estensione diagsession . Per analizzare manualmente l'utilizzo della CPU, vedere Analizzare le prestazioni usando la profilatura della CPU. In questo scenario, tuttavia, viene usato l'agente profiler.

    Al termine del test, l'agente riepiloga i risultati.

    L'agente segnala un potenziale miglioramento dell'efficienza di 33%, principalmente rimuovendo la materializzazione completa della tabella e una chiamata di metodo non necessaria ToList() .

    Screenshot dei risultati dei test.

    L'agente fornisce anche alcuni suggerimenti per i passaggi successivi, inclusa un'opzione per ottimizzare la query LINQ.

    Screenshot dei suggerimenti per il codice.

    Per questo esempio, ci si concentra sull'ottimizzazione della query LINQ.

  4. Selezionare il secondo suggerimento di Copilot e selezionare Invia per indicare all'agente di ottimizzare la catena di query LINQ.

    L'agente aggiorna Program.cs e fornisce suggerimenti aggiuntivi per ottimizzare il codice. Questi suggerimenti verranno ignorati per il momento.

  5. Esaminare le modifiche al codice in Program.cs.

    Screenshot delle modifiche al codice.

  6. In basso a destra dell'editor di codice esaminare le modifiche al codice e selezionare Mantieni per mantenerle.

    La query ottimizzata è illustrata qui.

     var optimized = db.People
         .AsNoTracking()
         .Where(p => p.Age > 50 && p.City.StartsWith("C"))
         .Select(p => p.Name)
         .Distinct()
         .OrderBy(n => n)
         .Take(10)
         .ToList();
    
  7. Per eseguire l'agente per eseguire ottimizzazioni aggiuntive, selezionare i suggerimenti forniti dall'agente o porre altre domande.

Continuare la chat dopo aver raggiunto il limite di token

L'agente Profiler fornisce riepiloghi intelligenti insieme alla continuazione del thread di chat, progettata per mantenere il tuo lavoro scorrevole senza interruzioni causate dai limiti dei token.

Se una chat con Copilot si avvicina al limite di token, viene richiesto di riepilogare e continuare in un nuovo thread.

Screenshot della sintesi dei thread.

Se si seleziona questa opzione, l'agente genera automaticamente un riepilogo conciso e ricco di contesto del thread di chat corrente e lo inoltra in una nuova conversazione. In questo modo è possibile evitare di ripercorrere qualsiasi passaggio.