mcpField
M
matlab-optimize-performance

matlab-optimize-performance

github.com/matlab开发1.2k90 次安装1 天前更新
代码仓库

关于 matlab-optimize-performance

为 MATLAB 用户提供系统化的性能优化工作流,按基准测量、性能分析、优化、复测和正确性验证逐步定位瓶颈。适用于函数、脚本及 GPU 代码的计时与改进。

主要功能

  1. 01建立运行时间基线
  2. 02使用 profiler 定位瓶颈
  3. 03依据分析选择优化模式
  4. 04复测并计算性能变化
  5. 05验证优化前后的结果一致性
  6. 06汇总优化结果

适用场景

  1. 01查找 MATLAB 函数或脚本的耗时位置
  2. 02比较代码修改前后的运行时间
  3. 03评估 GPU 代码的执行性能
  4. 04优化循环中的数组增长或重复计算

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-optimize-performance

安装后在 Claude Code 中输入/matlab-optimize-performance确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

manifest.yaml
references/
measurement-templates.md
optimization-patterns.md

详细介绍

MATLAB 性能优化工作流

用于查找和修复 MATLAB 代码性能瓶颈的系统化 7 步工作流。

适用场景

  • 用户要求加快或优化 MATLAB 代码
  • 用户想找出 MATLAB 代码运行缓慢的原因
  • 用户的函数或脚本运行时间过长
  • 用户要求对 MATLAB 代码进行基准测试或计时
  • 用户想比较更改前后的性能
  • 用户询问 MATLAB 性能最佳实践

不适用场景

  • 优化 Simulink 模型仿真速度(使用 Simulink Profiler)
  • 瓶颈位于无法在 M 代码层面更改的已编译 C/MEX 代码中
  • 性能问题纯粹受 I/O 限制(文件读取、网络、数据库)
  • 用户想编写性能测试(使用 writing-matlab-perf-tests 技能)

7 步工作流

第 1 步:建立基准

测量当前性能,以便有一个可供改进的数值基准。

针对单个函数:

f = @() targetFunction(input1, input2);
baseline = timeit(f);
fprintf('Baseline: %.4f s\n', baseline);

针对 GPU 代码:

f = @() gpuFunction(gpuInput);
baseline = gputimeit(f);

针对脚本或多步骤工作流:

% Warmup run (first call includes JIT compilation)
myWorkflow(inputs);

% Timed run
tic;
myWorkflow(inputs);
baseline = toc;
fprintf('Baseline: %.4f s\n', baseline);

推荐使用 timeit,因为它会自动预热并运行多个样本。

第 2 步:分析性能

找出实际耗时所在。不要猜测,务必进行性能分析。

profile on;
targetFunction(input1, input2);
profile off;
profile viewer;

查看性能分析器结果:

  1. 函数摘要——显示每个函数的总耗时和自身耗时。自身耗时是函数本身(不包括其被调用函数)所花费的时间。首先查看自身耗时最高的函数。
  2. 逐行详情——点击函数名称,查看每一行的耗时。这会揭示确切的瓶颈行。
  3. 调用次数——被调用数千次或数百万次的函数是优先优化目标。

提示:

  • 如果代码运行很快,请在循环中多次运行经过性能分析的代码,以便性能分析器收集足够的样本
  • 查看自身耗时,而非总耗时,以找到真正的瓶颈
  • 深入分析函数;摘要页面只能呈现部分情况
第 3 步:识别优化机会

根据性能分析结果,判断适用哪些模式。完整列表请参阅 references/optimization-patterns.md。

高影响模式:

模式典型加速比查找内容
向量化2–200 倍对数组执行逐元素计算的循环
预分配2–100 倍在循环中不断扩大的数组(x = [x; newRow])
避免不必要的重复计算2–50 倍多次计算相同的高开销表达式
discretize/histcounts2–50 倍对数据进行分箱或分类的循环
持久缓存1.5–95 倍重复调用 load() 或创建高开销对象
逻辑索引1.2–5 倍仅为对数组进行索引而使用 find()
arguments 块1.1–1.8 倍使用 inputParser 的函数
代数化简1.5–3 倍多余的 sqrt、abs 或矩阵运算

优化前,先确认目标是否值得优化:

  • 自身耗时是否超过总耗时的 10%?如果没有,优化它的作用不会很大。
  • 它是否在紧密循环中调用?高调用次数 × 短耗时 = 高总耗时。
  • 它是 M 代码还是内置函数?你无法让内置函数运行得更快,但通常可以减少调用次数(例如,将矩阵传给 filtfilt/filter,而不是循环处理各列)。
第 4 步:实施优化

应用第 3 步中识别的模式。完整模式列表及优化前后代码示例请参阅 references/optimization-patterns.md。

一般原则:

  • 从性能分析中影响最大的模式开始
  • 将循环中的不变工作移到循环外(对象创建、选项解析、常量表达式)
  • 尽可能用数组运算替代逐元素循环
  • 使用专用函数(discretize、cumsum、hypot),而非手写等效实现
  • 处理大型数据时,分批进行向量化以控制内存使用(参见目录中的模式 9)

示例——将不变工作移到循环外:

% Before: repeated expensive setup
for i = 1:n
    opts = optimoptions('fminunc', 'Display', 'off');
    result(i) = fminunc(@(x) cost(x, data(i)), x0, opts);
end

% After: setup once
opts = optimoptions('fminunc', 'Display', 'off');
for i = 1:n
    result(i) = fminunc(@(x) cost(x, data(i)), x0, opts);
end
步骤 5:测量优化后的性能

使用与步骤 1 相同的方法重新测量:

f = @() optimizedFunction(input1, input2);
optimized = timeit(f);
speedup = baseline / optimized;
fprintf('Optimized: %.4f s (%.2fx speedup)\n', optimized, speedup);

加速比达到 1.2x 或更高才算显著。低于此值时,测量噪声会让人难以确信这项改动确实带来了提升。

步骤 6:验证正确性

每项优化都必须产生与原始版本相同的结果:

original = originalFunction(input1, input2);
fast = optimizedFunction(input1, input2);

% Numeric comparison (allows floating-point tolerance)
maxErr = max(abs(original(:) - fast(:)));
fprintf('Max error: %.2e\n', maxErr);
assert(maxErr < 1e-10, 'Results differ beyond tolerance!');

对于非数值输出:

assert(isequal(original, fast), 'Results differ!');

如果结果因浮点运算顺序改变(例如,以不同顺序求和)而略有差异,通常可以接受。请记录预期的容差。

步骤 7:报告结果

总结所做的改动及其带来的提升:

fprintf('\n=== Performance Optimization Report ===\n');
fprintf('Target: %s\n', funcName);
fprintf('Baseline: %.4f s\n', baseline);
fprintf('Optimized: %.4f s\n', optimized);
fprintf('Speedup: %.2fx\n', speedup);
fprintf('Correctness: max error = %.2e\n', maxErr);
fprintf('Pattern applied: %s\n', patternName);

进行多项优化时,请分别报告每项优化的加速比,以及端到端的整体提升。

关键规则

  1. 优化前务必先分析性能——不要猜测瓶颈所在
  2. 一次只做一项改动——每次优化后都进行测量,以确定哪些改动有效
  3. 验证正确性——每项优化都必须产生等效输出
  4. 1.2x 阈值——低于 1.2x 的加速比无法与噪声可靠地区分
  5. GPU 计时——在 GPU 代码计时前后务必执行 wait(gpuDevice)
  6. 使用 timeit——它会处理预热和平均;基准测试应避免直接使用 tic/toc

常见错误

错误问题所在正确做法
未进行性能分析就优化你可能会改错地方先分析性能(步骤 2)
未预热就单次使用 tic/toc会计入 JIT 编译时间使用 timeit,或添加一次预热调用
未同步就测量 GPU 代码GPU 操作是异步的;toc 会提前触发前后都执行 wait(gpuDevice)
在循环中扩展数组每次追加都会复制整个数组在循环前预分配
盲目对超大数组进行向量化可能超出内存限制处理大型数据时使用分块处理
只报告子函数的加速比如果子函数仅占总耗时的 5%,这样的报告会产生误导务必报告端到端计时结果
认为速度更快就代表正确错误可能让代码变快(例如跳过了某些工作)务必验证结果是否一致(步骤 6)

参考文件

  • references/optimization-patterns.md — 优化模式完整目录,包含代码示例和测得的加速比
  • references/measurement-templates.md — 各工作流步骤可直接使用的 MATLAB 脚本模板

版权所有 2026 The MathWorks, Inc.

评论

支持 Markdown