使用 GitHub Copilot 分析应用

本文介绍如何使用 Copilot 和 Copilot 探查器代理分析应用程序并提高性能。

Copilot 通过推荐与代码匹配的分析工具,以及分析分析工具识别的特定问题来帮助你。

探查器代理将指导你完成性能测试和改进,可与 GitHub Copilot 一起工作,以便:

  • 分析 CPU 使用率、内存分配和运行时行为。
  • 表面性能瓶颈。
  • 生成 BenchmarkDotNet 基准 或优化现有的 BenchmarkDotNet 基准。
  • 应用建议的优化。
  • 验证引导循环中的改进。

探查器代理在以下情况下特别有用:

  • 不熟悉分析。
  • 你不确定从何处开始进行性能优化。
  • 你想要使用实际基准验证优化。
  • 你正在处理高性能应用,例如游戏、服务或客户端工具。

有关 Copilot 代理和代理模式的一般信息,请参阅 使用 Copilot 代理模式

先决条件

若要开始,需要:

AI 增强方案

Copilot 了解代码和 Visual Studio 分析工具。 因此,你可以与探查器感知 AI 交互,询问与代码相关的详细问题以及一般的性能问题。

Copilot 为某些目标方案提供更精确的帮助,例如下表中所述的方案。

功能或方案 Link
CPU 使用率的代理定向分析 请参阅本文中的 Profiler 代理的配置文件
用于分析的自动见解 请参阅 获取有关自动见解的 AI 帮助
用于检测的自动见解 请参阅 获取 AI 帮助
.NET 对象分配的自动见解 请参阅 获取 AI 帮助
Copilot 工具建议 请参阅分析工具概述中的“获取 AI 建议”部分

在这些方案中,可以使用获取目标帮助。或使用 Screenshot of Ask Copilot button.Copilot 按钮进行分析。 Copilot 已经知道你的问题的上下文。 例如,它了解分析工具发现的见解,并可以提供有关如何修复这些见解的相关建议。

使用 Copilot Profiler 代理的配置文件

以下示例演示如何使用 Copilot Profiler 代理收集性能数据,然后使用它分析结果,并建议并进行修复。

启动分析会话

  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 代理。

    调用探查器代理的屏幕截图。

    或者,可以通过手动选择 “选择工具 ”并手动启用 Profiler 代理,然后切换到代理模式来启动探查器代理。 使用此方法时,无需使用 @Profiler 命令。

    Copilot 询问是否要运行探查器。

    启动分析请求的屏幕截图。

  3. 选择 “确认”。

    代理独立运行一系列步骤。 它检查代码,为 BenchmarkDotNet 项目添加支持,包括项目引用和包,将基准添加到新文件中,并针对它生成的新代码运行比较测试。

    基准结果显示在“输出”窗口中,输出设置为 “诊断中心”。

    基准输出的屏幕截图。

    诊断会话的结果显示在 .diagsession 文件报告中。 若要手动调查 CPU 使用率,请参阅 使用 CPU 分析分析分析性能。 但是,在此方案中,我们将改用 Profiler 代理。

    完成测试后,代理将总结其发现。

    代理报告潜在的 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. 如果要代理进行其他优化,请选择代理提供的建议或提出其他问题。

达到令牌限制后继续聊天

Profiler 代理提供智能摘要以及聊天线程延续,旨在保持工作流,而不会因达到令牌限制而受到阻止。

如果与 Copilot 的聊天接近其令牌上限,系统会提示你选择在新的线程中汇总并继续。

线程摘要的屏幕截图。

如果选择此选项,代理会自动生成当前聊天线程的简洁上下文丰富的摘要,并将其转发到新的对话中。 这样就可以避免重走任何步骤。