Sdílet prostřednictvím


Profilování aplikace pomocí agenta GitHub Copilot Profiler

Agent GitHub Copilot Profiler spolupracuje s GitHub Copilotem a provede vás testováním a vylepšováním výkonu.

Tento kurz ukazuje, jak profilovat aplikace a zlepšit výkon pomocí agenta Copilot Profiler.

Agent Profiler může provádět všechny následující úlohy.

  • Analýza využití procesoru, přidělení paměti a chování modulu runtime
  • Kritické body výkonu zařízení Surface
  • Generování srovnávacích testů BenchmarkDotNet nebo optimalizace existujících srovnávacích testů BenchmarkDotNet
  • Použijte navrhované optimalizace.
  • Ověřte vylepšení ve smyčce s asistencí.

Agent profileru je užitečný zejména v následujících případech:

  • Neznáte profilaci.
  • Nejste si jisti, kde začít s laděním výkonu.
  • Chcete ověřit optimalizace pomocí skutečných srovnávacích testů.
  • Pracujete na vysoce výkonných aplikacích, jako jsou hry, služby nebo klientské nástroje.

Informace o dalších funkcích profilace v Copilotu najdete ve scénářích s rozšířenými AI. Obecné informace o agentech Copilot a režimu agenta naleznete v tématu Použití režimu agenta Copilot.

Požadavky

Abyste mohli začít, potřebujete:

Zahájení relace profilace

  1. V sadě Visual Studio vytvořte novou konzolovou aplikaci jazyka C#.

    V úvodním okně zvolte Vytvořit nový projekt. Do vyhledávacího pole zadejte konzolu , vyberte jazyk C# a pak zvolte Konzolová aplikace pro .NET. Zvolte Další. Zadejte název projektu, například ConsoleApp_CopilotProfile , a vyberte Další. Zvolte cílovou architekturu (například .NET 8) a zvolte Vytvořit.

  2. V Průzkumníku řešení klikněte pravým tlačítkem myši na uzel Závislosti v projektu, zvolte Spravovat balíčky NuGet, vyhledejte EntityFramework a pak do projektu přidejte následující balíčky:

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

    Aplikace používá databázi v paměti ke zjednodušení nastavení projektu.

  3. Nahraďte kód v Program.cs následujícím kódem:

    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. Vyberte Sestavit řešení sestavení>, abyste měli jistotu, že se aplikace sestaví bez chyb.

Zeptejte se Copilotu na přehledy profilace.

  1. Otevřete okno chatu Copilot a použijte následující výzvu.

    @Profiler Please evaluate the performance of this code

  2. Vyberte Odeslat.

    Příkaz @Profiler volá agenta Copilot Profiler.

    Snímek obrazovky s vyvoláním agenta profileru

    Případně můžete spustit agenta profileru ručním výběrem možnosti Vybrat nástroje a ručním povolením agenta profileru a následným přepnutím do režimu agenta agenta. Pomocí této metody nemusíte tento příkaz používat @Profiler .

    Copilot se zeptá, jestli chcete profiler spustit.

    Snímek obrazovky s žádostí o zahájení profilace

  3. Zvolte Potvrdit.

    Agent prochází řadou kroků nezávisle. Prozkoumá kód, přidá do projektu podporu pro BenchmarkDotNet, včetně odkazů na projekt a balíčků, přidá srovnávací testy do nového souboru a spustí srovnávací test s novým kódem, který generuje.

    Výsledky srovnávacích testů se zobrazí v okně Výstup s výstupem nastaveným na diagnostické centrum.

    Snímek obrazovky s výstupem srovnávacího testu

    Výsledky z diagnostické relace se zobrazí v sestavě souboru .diagsession . Pokud chcete ručně prozkoumat využití procesoru, přečtěte si téma Analýza výkonu pomocí profilace procesoru. V tomto scénáři ale místo toho používáme agenta Profileru.

    Po dokončení testování agent shrnuje svá zjištění.

    Agent hlásí potenciálních 33% zvýšení efektivity, zejména odstraněním materializace full-table a nepotřebným ToList() voláním metody.

    Snímek obrazovky s výsledky testu

    Agent také nabízí několik návrhů pro další kroky, včetně možnosti optimalizace dotazu LINQ.

    Snímek obrazovky s návrhy kódu

    V tomto příkladu se zaměříte na optimalizaci dotazu LINQ.

  4. Vyberte druhý návrh copilotu a výběrem možnosti Odeslat agentovi řekněte , aby optimalizoval řetěz dotazů LINQ.

    Agent aktualizuje Program.cs a poskytuje další návrhy pro optimalizaci kódu. Prozatím tyto návrhy přeskočíme.

  5. Podívejte se na změny kódu v Program.cs.

    Snímek obrazovky se změnami kódu

  6. V pravém dolním rohu editoru kódu prozkoumejte změny kódu a vyberte Zachovat , abyste je zachovali.

    Optimalizovaný dotaz se tady zobrazí.

     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. Pokud chcete agenta provést další optimalizace, vyberte buď návrhy poskytnuté agentem, nebo položte další otázky.

Pokračovat v chatu po dosažení limitu tokenu

Agent Profiler poskytuje inteligentní sumarizaci spolu s pokračováním vlákna chatu, která je navržená tak, aby vaše práce fungovala bez blokování dosažením limitů tokenů.

Pokud se chat s Copilotem blíží ke svému limitu tokenu, zobrazí se výzva k vytvoření souhrnu a pokračování v novém vlákně.

Snímek obrazovky se souhrnem vláken

Pokud vyberete tuto možnost, agent automaticky vygeneruje stručný kontextový souhrn aktuálního vlákna chatu a přenese ho do nové konverzace. To vám umožní vyhnout se retracování jakýchkoli kroků.