news 2026/4/26 22:02:56

【译】Copilot Profiler Agent —— 分析任务交由 AI,应用性能不受影响

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【译】Copilot Profiler Agent —— 分析任务交由 AI,应用性能不受影响

在 Visual Studio 2026 中,我们推出了 Copilot Profiler Agent,这是一款新的人工智能驱动的助手,可帮助您分析和优化代码中的性能瓶颈。通过将 GitHub Copilot 的功能与 Visual Studio 的性能分析器相结合,您现在可以用自然语言询问有关性能的问题,深入了解热点路径,并快速发现优化机会。让我们来看一个真实的例子,了解这款工具如何帮助您实现有意义的性能改进。

对实际项目进行基准测试

为了展示 Copilot Profiler Agent 的功能,让我们对一个广受欢迎的开源项目 CsvHelper 进行优化。您可以按照以下步骤操作:克隆我的代码仓库分支,然后通过“git checkout 435ff7c”命令切换到我修复之前的版本,我们将在下文详细介绍该修复。

在我之前的一篇博客文章中,我添加了一个 CsvHelper.Benchmarks 项目,其中包含一个用于读取 CSV 记录的基准测试。这次我想看看我们是否可以优化 CSV 记录的写入。通常,我会通过为想要优化的代码创建基准测试来开始这项研究,不过虽然我们仍然会这样做,但我们可以让 Copilot 来承担这些繁重的工作。在 Copilot 聊天窗口中,我可以问@Profiler “帮我为 #WriteRecords 方法编写一个基准测试”。@Profiler 让我们直接与 Copilot Profiler Agent 对话,而 #WriteRecords 则明确告诉它我们要进行基准测试的方法。

从这里开始,Copilot 着手创建我们的新基准测试,它会询问我们是否可以安装分析器的 NuGet 包,以便在运行基准测试时从中提取信息。它还会根据找到的任何现有基准测试来构建新的基准测试模型,因此生成的基准测试与我们已经编写的非常相似,从而保持与存储库风格的一致性。最后,它会启动构建过程,以确保一切正常。

完成后,它会提供一些有用的后续提示来启动调查。我们可以点击其中一个来展开调查,不过我想对基准测试做些细微的修改。

我对基准测试做了些调整,增加了几个供我们写入的字段,这里具体是 2 个整数字段和 2 个字符串字段。在为这篇博客撰写内容之前,我最初让 Copilot 来做这件事时,它每次都是写入一个新的内存流,而不是同一个内存流。写入同一个内存流或许是更好的做法,这次算你赢了 Copilot,但在我给 CsvHelper 提交的最初的拉取请求中,我并没有这么做,不过应该也没什么问题。

public class BenchmarkWriteCsv { private const int entryCount = 10000; private readonly List records = new(entryCount); public class Simple { public int Id1 { get; set; } public int Id2 { get; set; } public string Name1 { get; set; } public string Name2 { get; set; } } [GlobalSetup] public void GlobalSetup() { var random = new Random(42); var chars = new char[10]; string getRandomString() { for (int i = 0; i < 10; ++i) chars[i] = (char)random.Next('a', 'z' + 1); return new string(chars); } for (int i = 0; i < entryCount; ++i) { records.Add(new Simple { Id1 = random.Next(), Id2 = random.Next(), Name1 = getRandomString(), Name2 = getRandomString(), }); } } [Benchmark] public void WriteRecords() { using var stream = new MemoryStream(); using var streamWriter = new StreamWriter(stream); using var writer = new CsvHelper.CsvWriter(streamWriter, CultureInfo.InvariantCulture); writer.WriteRecords(records); streamWriter.Flush(); } }

深入了解基准测试

现在开始分析,我既可以让 Profiler Agent 运行基准测试,也可以直接点击后续提示“@Profiler Run the benchmark and analyze results”。从这里开始,Copilot 会编辑我的主方法,乍一看可能有些奇怪,但查看所做的更改后,我发现它为了使用 BenchmarkSwitcher 进行了必要的修改,这样就能选择要运行的基准测试了:

static void Main(string[] args) { // Use assembly-wide discovery so all benchmarks in this assembly are run, // including the newly added BenchmarkWriteRecords. _ = BenchmarkSwitcher.FromAssembly(typeof(BenchmarkEnumerateRecords).Assembly).Run(args); }

然后它启动了一次基准测试运行,完成后会给我一个诊断会话,我可以在其中开始调查。

使用 Copilot Profiler Agent 来查找瓶颈

现在到了令人兴奋的部分。运行基准测试后,Profiler Agent 会分析跟踪信息,并突出显示时间的消耗位置。我可以向 Profiler Agent 询问有关跟踪的问题,让它解释代码为什么运行缓慢,或者某些优化为何会有帮助。它已经指出,大部分时间都花在委托编译和调用上,这是针对 CSV 记录中的每个字段进行的。对于一个有 4 个字段、被写入 10,000 次的记录来说,这意味着会有 40,000 次委托调用。每次调用都有开销,而这在分析器中显示为一个热点路径。

我可以问 Profiler Agent:“我怎样才能减少委托调用的开销?”或者“为什么委托调用很慢?”,而它会像一位耐心的老师一样解释相关概念并提出修复建议。

实施修复方案

我点击 @Profiler Optimize library to produce a single compiled write delegate (reduce multicast invokes),看看会得到什么结果。 Profiler Agent 会对 ObjectRecordWriter 进行编辑,我可以在聊天窗口中点击它来查看所做更改的差异。

查看当前的实现,代码构建了一个委托列表,每个字段对应一个委托:

var delegates = new List<Action>(); foreach (var memberMap in members) { // ... field writing logic ... delegates.Add(Expression.Lambda<Action>(writeFieldMethodCall, recordParameter).Compile()); } var action = CombineDelegates(delegates) ?? new Action((T parameter) => { }); return action;

问题在于 CombineDelegates 会创建一个多播委托,该委托会依次单独调用每个独立的委托。相反,Profiler Agent 建议我们在编译前使用 Expression.Block 来组合所有表达式:

var expressions = new List<Expression>(members.Count); foreach (var memberMap in members) { // ... field writing logic ... expressions.Add(writeFieldMethodCall); } if (expressions.Count == 0) { return new Action<T>((T parameter) => { }); } // Combine all field writes into a single block var block = Expression.Block(expressions); return Expression.Lambda<Action<T>>(block, recordParameter).Compile();

这一改动虽小却很精妙:我们没有创建多个委托并按顺序调用它们,而是创建了一个包含所有字段写入操作的单个块表达式,然后对其进行一次编译。现在,当我们为每条记录调用委托时,所有字段都会在一次调用中完成写入,不存在额外的委托开销。

衡量影响

做出这一更改后,Copilot 会自动重新运行基准测试以衡量改进效果。结果显示,在此次使用分析器的运行中,性能大约提升了 24%。我们之前为 CsvHelper 准备的分阶段拉取请求显示性能提升了约 15%。CPU 分析器证实,我们已经消除了委托调用的开销,对于每条有 4 个字段的 10,000 条记录,之前需要进行 40,000 次委托调用,而现在只需要 10,000 次委托调用。

对于一个已经经过大量优化的库来说,这是一场意义重大的胜利。对于那些编写包含许多字段的大型 CSV 文件的应用程序而言,这一改进直接意味着 CPU 时间的减少和处理速度的提升。而且,由于 CsvHelper 的下载量高达数百万次,这项优化惠及了大量用户。在此基础上,我继续推进并提交了拉取请求,不过 Copilot 贴心地提供了更多关于类型转换和 ShouldQuote 逻辑的后续提示,以便我能进一步提升性能。

Copilot Profiler Agent 的价值

这个工作流程之所以强大,是因为它将 Visual Studio Profiler 提供的精确性能数据与 Copilot 的分析和代码生成能力相结合。您无需手动深入研究 CPU 跟踪并试图理解热点路径的含义,而是可以提出自然语言问题,获取可执行的见解,并快速测试想法。

该 Agent 不仅会告诉您哪些部分运行缓慢,还会帮助您理解其缓慢的原因,并提出具体的修复方法。在这种情况下,它识别出委托调用的开销是瓶颈,并建议采用 Expression.Block 优化,这正是解决该问题的正确方案。它甚至还重新运行了基准测试来确认该优化的效果!

让我们知道您的想法

我们已经展示了 Copilot Profiler Agent 如何帮助您处理实际项目,通过自然语言查询识别性能瓶颈,并在数据支持下做出有意义的改进。当您能够就性能数据提出问题并获得智能答案时,测量/更改/测量的循环会变得快得多。我们很想听听您的想法!

原文链接:https://devblogs.microsoft.com/visualstudio/delegate-the-analysis-not-the-performance/

作者:MeteorSeed

我希望您喜欢这篇博文,并一如既往地感谢您阅读并与朋友和同事分享我的博文。

转载请注明出处。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/26 22:02:55

GLM-TTS适合教育领域吗?智能教学助手应用场景探索

GLM-TTS在教育领域的应用潜力&#xff1a;构建智能教学助手的新范式 在“双减”政策推动个性化学习、AI技术加速渗透校园的今天&#xff0c;教师的时间愈发宝贵——备课、批改作业、设计互动环节&#xff0c;每一项都要求高度投入。而当一位语文老师需要为《春晓》录制一段声情…

作者头像 李华
网站建设 2026/4/23 16:18:37

GLM-TTS输出路径说明:轻松找到你生成的每一个音频文件

GLM-TTS输出路径说明&#xff1a;轻松找到你生成的每一个音频文件 在语音合成系统越来越“黑盒化”的今天&#xff0c;一个看似不起眼却极为关键的问题浮出水面&#xff1a;我刚生成的那段语音&#xff0c;到底存到哪儿去了&#xff1f; 尤其是在使用像 GLM-TTS 这类基于大语言…

作者头像 李华
网站建设 2026/4/25 23:19:43

语音合成速度慢?这份GLM-TTS性能优化清单请收好

语音合成速度慢&#xff1f;这份GLM-TTS性能优化清单请收好 在短视频配音、AI主播、有声书自动生成等应用日益普及的今天&#xff0c;用户对语音合成系统的要求早已不止“能出声”这么简单。越来越多的开发者和内容创作者发现&#xff1a;功能强大的模型&#xff0c;往往卡在“…

作者头像 李华
网站建设 2026/4/25 11:58:08

金融-租赁:资产管理系统折旧计算测试报告

折旧计算在资产管理系统中的核心作用‌ 资产管理系统&#xff08;AMS&#xff09;是金融租赁行业的核心工具&#xff0c;用于跟踪资产全生命周期&#xff0c;其中折旧计算直接影响财务报告、税务合规和决策制定。在金融租赁场景下&#xff0c;折旧逻辑复杂&#xff08;如直线法…

作者头像 李华
网站建设 2026/4/25 21:10:34

一次性解决跨域难题:构建高效PHP CORS响应的8步法则

第一章&#xff1a;一次性解决跨域难题&#xff1a;构建高效PHP CORS响应的8步法则在现代Web开发中&#xff0c;前后端分离架构已成为主流&#xff0c;而跨域资源共享&#xff08;CORS&#xff09;问题也随之成为高频痛点。PHP作为服务端常用语言&#xff0c;合理配置CORS响应头…

作者头像 李华