Udostępnij przez


Profilowanie aplikacji za pomocą agenta profilera Copilot w usłudze GitHub

Agent Profilera GitHub Copilot działa obok GitHub Copilot i prowadzi Cię przez testowanie wydajności oraz wprowadzanie ulepszeń.

W tym samouczku pokazano, jak optymalizować aplikacje i zwiększyć ich wydajność przy użyciu narzędzia Copilot Profiler Agent.

Agent profilera może wykonywać wszystkie poniższe zadania.

  • Analizowanie użycia procesora CPU, alokacji pamięci i zachowania środowiska uruchomieniowego.
  • Wąskie gardła wydajności powierzchni.
  • Generowanie testów porównawczych BenchmarkDotNet lub optymalizowanie istniejących testów porównawczych BenchmarkDotNet.
  • Zastosuj sugerowane optymalizacje.
  • Weryfikowanie ulepszeń w pętli z przewodnikiem.

Agent profilera jest szczególnie przydatny, gdy:

  • Nie znasz profilowania.
  • Nie masz pewności, gdzie zacząć od dostrajania wydajności.
  • Chcesz zweryfikować optymalizacje przy użyciu rzeczywistych testów porównawczych.
  • Pracujesz nad aplikacjami o wysokiej wydajności, takimi jak gry, usługi lub narzędzia klienckie.

Aby uzyskać informacje o innych funkcjach profilowania w aplikacji Copilot, zobacz Scenariusze rozszerzone o sztuczną inteligencję. Aby uzyskać ogólne informacje na temat agentów Copilot i trybu agenta, zobacz Use Copilot agent mode (Używanie trybu agenta Copilot).

Wymagania wstępne

Aby rozpocząć pracę, potrzebne są następujące elementy:

Rozpoczynanie sesji profilowania

  1. W programie Visual Studio utwórz nową aplikację konsolową języka C#.

    W oknie uruchamiania wybierz pozycję Utwórz nowy projekt. Wpisz konsolę w polu wyszukiwania, wybierz pozycję C# jako język, a następnie wybierz pozycję Aplikacja konsolowa dla platformy .NET. Wybierz Dalej. Wpisz nazwę projektu, taką jak ConsoleApp_CopilotProfile , a następnie wybierz pozycję Dalej. Wybierz platformę docelową (na przykład .NET 8) i wybierz pozycję Utwórz.

  2. W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy węzeł Zależności w projekcie, wybierz pozycję Zarządzaj pakietami NuGet, wyszukaj pozycję EntityFramework, a następnie dodaj następujące pakiety do projektu:

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

    Aplikacja używa bazy danych w pamięci, aby uprościć konfigurację projektu.

  3. Zastąp kod w Program.cs następującym kodem:

    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. Wybierz pozycję Kompiluj > rozwiązanie kompilacji , aby upewnić się, że aplikacja kompiluje się bez błędów.

Poproś copilot o profilowanie szczegółowych informacji

  1. Otwórz okno czatu copilot i użyj następującego monitu.

    @Profiler Please evaluate the performance of this code

  2. Wybierz Wyślij.

    Polecenie @Profiler wywołuje agenta Copilot Profiler.

    Zrzut ekranu przedstawiający wywoływanie agenta profilera.

    Alternatywnie możesz uruchomić agenta profilera, ręcznie wybierając pozycję Wybierz narzędzia i ręcznie włączając agenta Profilera, a następnie przełączając się do trybu agenta. Korzystając z tej metody, nie musisz używać @Profiler polecenia .

    Copilot, czy chcesz uruchomić profilera.

    Zrzut ekranu przedstawiający rozpoczynanie żądania profilowania.

  3. Wybierz pozycję Potwierdź.

    Agent wykonuje serię kroków niezależnie. Analizuje kod, dodaje obsługę projektu BenchmarkDotNet, w tym odwołania do projektu i pakiety, dodaje testy porównawcze do nowego pliku i uruchamia test porównawczy dla nowego kodu, który generuje.

    Wyniki testu porównawczego są wyświetlane w oknie Dane wyjściowe z danymi wyjściowymi ustawionymi na Centrum diagnostyki.

    Zrzut ekranu przedstawiający dane wyjściowe testu porównawczego.

    Wyniki sesji diagnostyki są wyświetlane w raporcie pliku diagsession . Jeśli chcesz ręcznie zbadać użycie procesora CPU, zobacz Analizowanie wydajności przy użyciu profilowania procesora CPU. Jednak w tym scenariuszu używamy agenta profilera.

    Po zakończeniu testowania agent podsumowuje swoje wyniki.

    Agent zgłasza potencjalne 33% wzrost wydajności, głównie poprzez usunięcie materializacji pełnej tabeli i niepotrzebne ToList() wywołanie metody.

    Zrzut ekranu przedstawiający wyniki testu.

    Agent udostępnia również kilka sugestii dotyczących następnych kroków, w tym opcję optymalizacji zapytania LINQ.

    Zrzut ekranu przedstawiający sugestie dotyczące kodu.

    W tym przykładzie skoncentrujesz się na optymalizacji zapytania LINQ.

  4. Wybierz drugą sugestię copilot i wybierz pozycję Wyślij , aby poinformować agenta o optymalizacji łańcucha zapytań LINQ.

    Agent aktualizuje Program.cs i udostępnia dodatkowe sugestie dotyczące optymalizacji kodu. Na razie pominiemy te sugestie.

  5. Przyjrzyj się zmianom kodu w Program.cs.

    Zrzut ekranu przedstawiający zmiany kodu.

  6. W prawym dolnym rogu edytora kodu sprawdź zmiany kodu i wybierz pozycję Zachowaj , aby je zachować.

    W tym miejscu pokazano zoptymalizowane zapytanie.

     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. Jeśli chcesz, aby agent wprowadzał dodatkowe optymalizacje, wybierz sugestie dostarczone przez agenta lub zadaj dodatkowe pytania.

Kontynuuj czat po osiągnięciu limitu tokenów

Agent profilujący zapewnia inteligentne podsumowania oraz kontynuację wątku czatu, co ma na celu utrzymanie płynności pracy bez blokowania przez osiągnięcie limitów tokenów.

Jeśli czat z Copilotem zbliża się do limitu tokenów, masz możliwość podsumowania i rozpoczęcia nowego wątku.

Zrzut ekranu przedstawiający podsumowanie wątków.

Jeśli wybierzesz tę opcję, agent automatycznie wygeneruje zwięzłe, kontekstowe podsumowanie bieżącego wątku czatu i przeprowadzi go do nowej konwersacji. Pozwala to uniknąć ponownego wykonywania wszelkich kroków.