性能优化 #
一、性能分析 #
1.1 tic和toc #
matlab
% 计时
tic;
result = my_function();
elapsed = toc;
fprintf('耗时: %.4f 秒\n', elapsed);
1.2 timeit函数 #
matlab
% 更精确的计时
t = timeit(@() my_function(x));
fprintf('平均耗时: %.4f 秒\n', t);
1.3 Profiler #
matlab
% 启动Profiler
profile on;
% 运行代码
my_function();
% 查看结果
profile viewer;
profile off;
% 获取数据
p = profile('info');
二、向量化 #
2.1 避免循环 #
matlab
% 不推荐:循环
n = 1e6;
result = zeros(1, n);
for i = 1:n
result(i) = sin(i);
end
% 推荐:向量化
result = sin(1:n);
2.2 向量化运算 #
matlab
% 元素运算
A = rand(1000, 1000);
B = rand(1000, 1000);
% 矩阵运算(向量化)
C = A .* B; % 元素乘法
C = A + B; % 加法
C = A .^ 2; % 元素平方
% 避免循环
% 不推荐
for i = 1:size(A, 1)
for j = 1:size(A, 2)
C(i, j) = A(i, j) * B(i, j);
end
end
% 推荐
C = A .* B;
2.3 使用内置函数 #
matlab
% 不推荐:手动实现
function s = my_sum(A)
s = 0;
for i = 1:length(A)
s = s + A(i);
end
end
% 推荐:使用内置函数
s = sum(A);
三、预分配 #
3.1 数组预分配 #
matlab
% 不推荐:动态扩展
tic;
data = [];
for i = 1:10000
data = [data, rand()];
end
toc; % 较慢
% 推荐:预分配
tic;
data = zeros(1, 10000);
for i = 1:10000
data(i) = rand();
end
toc; % 较快
3.2 元胞数组预分配 #
matlab
% 预分配元胞数组
data = cell(1, 10000);
for i = 1:10000
data{i} = rand();
end
3.3 结构体数组预分配 #
matlab
% 预分配结构体数组
data = struct('x', cell(1, 10000), 'y', cell(1, 10000));
for i = 1:10000
data(i).x = rand();
data(i).y = rand();
end
四、内存优化 #
4.1 选择合适的数据类型 #
matlab
% 使用合适的数据类型
data_int8 = int8(randi([0 255], 1000, 1000)); % 1 MB
data_double = double(randi([0 255], 1000, 1000)); % 8 MB
% 使用single
data_single = single(rand(1000, 1000)); % 4 MB
data_double = double(rand(1000, 1000)); % 8 MB
4.2 避免不必要的复制 #
matlab
% 不推荐:创建副本
A = rand(10000);
B = A; % 复制
B(1) = 0; % 触发写时复制
% 推荐:直接操作
A = rand(10000);
A(1) = 0;
4.3 及时清除变量 #
matlab
% 处理大数据后清除
large_data = rand(10000);
result = sum(large_data(:));
clear large_data; % 释放内存
五、并行计算 #
5.1 parfor #
matlab
% 普通for循环
tic;
result = zeros(1, 1000);
for i = 1:1000
result(i) = sum(rand(1000));
end
toc;
% 并行for循环
tic;
result = zeros(1, 1000);
parfor i = 1:1000
result(i) = sum(rand(1000));
end
toc;
5.2 并行池 #
matlab
% 启动并行池
pool = parpool;
% 关闭并行池
delete(pool);
% 检查并行池状态
pool = gcp('nocreate');
if isempty(pool)
parpool;
end
5.3 并行计算注意事项 #
matlab
% parfor限制
parfor i = 1:1000
% 不能使用break、continue
% 变量分类要明确
result(i) = compute(i);
end
% 广播变量
param = 0.5;
parfor i = 1:1000
result(i) = compute(i, param); % param是广播变量
end
六、其他优化技巧 #
6.1 使用稀疏矩阵 #
matlab
% 稀疏矩阵
A = sparse(10000, 10000);
A(1, 1) = 1;
A(10000, 10000) = 1;
% 转换
A_full = full(A); % 稀疏转全
A_sparse = sparse(A_full); % 全转稀疏
6.2 使用MEX文件 #
matlab
% 对于计算密集型任务,可以使用C/C++编写MEX文件
% mex my_function.c
6.3 JIT优化 #
matlab
% MATLAB的JIT编译器会自动优化循环
% 确保循环体简单,避免复杂数据结构
七、性能对比示例 #
7.1 对比测试 #
matlab
function compare_performance()
n = 1e6;
% 方法1:循环
tic;
result1 = zeros(1, n);
for i = 1:n
result1(i) = sin(i);
end
t1 = toc;
% 方法2:向量化
tic;
result2 = sin(1:n);
t2 = toc;
fprintf('循环: %.4f 秒\n', t1);
fprintf('向量化: %.4f 秒\n', t2);
fprintf('加速比: %.2fx\n', t1/t2);
end
八、总结 #
本章学习了:
- 性能分析:tic/toc、timeit、Profiler
- 向量化:避免循环、使用内置函数
- 预分配:数组、元胞、结构体
- 内存优化:数据类型、避免复制
- 并行计算:parfor、并行池
下一章将学习工具箱的使用。
最后更新:2026-03-27