Поделиться через


Профилирование приложения с помощью агента профилировщика GitHub Copilot

Агент профилировщика GitHub Copilot работает вместе с GitHub Copilot и поможет вам проверить и улучшить производительность.

В этом руководстве показано, как профилировать приложения и повысить производительность с помощью агента Профилировщика Copilot.

Агент профилировщика может выполнять все следующие задачи.

  • Анализ использования ЦП, выделения памяти и поведения среды выполнения.
  • Узкие места производительности поверхности.
  • Создайте тесты BenchmarkDotNet или оптимизируйте существующие тесты BenchmarkDotNet.
  • Применение предлагаемых оптимизаций.
  • Проверьте улучшения в интерактивном цикле.

Агент профилировщика особенно полезен, когда:

  • Вы не знакомы с профилированием.
  • Вы не уверены, где начать с настройки производительности.
  • Вы хотите проверить оптимизацию с помощью реальных тестов.
  • Вы работаете над высокопроизводительные приложения, такие как игры, службы или клиентские инструменты.

Для получения информации о других функциях профилирования в Copilot см. в разделе о расширенных ИИ-сценариях. Общие сведения об агентах Copilot и режиме агента см. в разделе "Использование режима агента Copilot".

Предпосылки

Чтобы начать, вам нужно:

Запуск сеанса профилирования

  1. В Visual Studio создайте консольное приложение C#.

    В окне запуска нажмите кнопку "Создать проект". Введите консоль в поле поиска, выберите язык C# и выберите консольное приложение для .NET. Нажмите кнопку Далее. Введите имя проекта, например ConsoleApp_CopilotProfile , и нажмите кнопку "Далее". Выберите целевую платформу (например, .NET 8) и нажмите кнопку "Создать".

  2. В обозревателе решений щелкните правой кнопкой мыши узел зависимостей в проекте, выберите "Управление пакетами NuGet", выполните поиск EntityFramework и добавьте в проект следующие пакеты:

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

    Приложение использует базу данных в памяти для упрощения настройки проекта.

  3. Замените код в Program.cs следующим кодом:

    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. Выберите "Сборка решения сборки > " , чтобы убедиться, что приложение выполняет сборку без ошибок.

Попросите Copilot получить аналитические сведения о профилировании

  1. Откройте окно чата Copilot и используйте следующую строку.

    @Profiler Please evaluate the performance of this code

  2. Выберите Отправить.

    Команда @Profiler вызывает агент Профилировщика Copilot.

    Снимок экрана: вызов агента профилировщика.

    Кроме того, можно запустить агент профилировщика вручную, выбрав "Выбрать инструменты " и вручную включив агент профилировщика, а затем переключившись в режим агента. Используя этот метод, вам не нужно использовать @Profiler команду.

    Copilot спрашивает, хотите ли вы запустить профилировщик.

    Снимок экрана: запрос на профилирование.

  3. Нажмите кнопку "Подтвердить".

    Агент выполняется через ряд шагов независимо друг от друга. Он проверяет код, добавляет поддержку проекта для BenchmarkDotNet, включая ссылки на проекты и пакеты, добавляет тесты тестирования в новый файл и запускает тест сравнения с новым кодом, который он создает.

    Результаты теста отображаются в окне вывода с выходными данными, установленными в Центре диагностики.

    Снимок экрана: выходные данные теста.

    Результаты сеанса диагностики отображаются в отчете файла diagsession . Если вы хотите вручную изучить использование ЦП, см. статью "Анализ производительности с помощью профилирования ЦП". Однако в этом сценарии мы используем агент профилировщика.

    По завершении тестирования агент суммирует свои результаты.

    Агент сообщает о потенциальных 33% повысить эффективность, главным образом путем удаления полно табличного материализации и ненужных ToList() вызовов метода.

    Снимок экрана: результаты теста.

    Агент также предоставляет несколько предложений для дальнейших действий, включая вариант оптимизации запроса LINQ.

    Снимок экрана: предложения кода.

    В этом примере основное внимание уделяется оптимизации запроса LINQ.

  4. Выберите второе предложение Copilot и нажмите кнопку "Отправить ", чтобы сообщить агенту, чтобы оптимизировать цепочку запросов LINQ.

    Агент обновляет Program.cs и предоставляет дополнительные предложения по оптимизации кода. Сейчас мы пропустим эти предложения.

  5. Ознакомьтесь с изменениями кода в Program.cs.

    Снимок экрана: изменения кода.

  6. В правом нижнем углу редактора кода проверьте изменения кода и нажмите кнопку "Сохранить ".

    Здесь показан оптимизированный запрос.

     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. Если вы хотите выполнить дополнительную оптимизацию, выберите предложения, предоставленные агентом, или задайте дополнительные вопросы.

Продолжение чата после достижения лимита токенов

Агент профилировщика предоставляет умное резюмирование и продление истории чата, предназначенное для поддержания рабочего потока без блокировок из-за ограничения токенов.

Если чат с Copilot приближается к его лимиту токенов, вам будет предложено подвести итоги и продолжить в новой ветке.

Снимок экрана: сводка обсуждения.

Если вы выберете этот параметр, агент автоматически создает краткую, многофункциональную контекстную сводку текущего потока чата и переносит ее в новую беседу. Это позволяет избежать повторения каких-либо шагов.