打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
MATLAB标准性能优化技术 — 循环优化(2)
userphoto

2023.05.30 江苏

关注

MATLAB标准性能优化技术 — 循环优化(1)的基础上继续介绍循环优化的相关方法。

01

提前结束循环

MATLAB 的 continue 命令用于直接跳到下一个循环迭代(或者如果这已经是最后一次迭代,则结束循环)。
break 用于跳出所有剩余的循环迭代并直接跳转到包含循环的代码之后。提前结束可以节省不必要的循环迭代计算。
例如对向量A中的元素进行循环,如果希望跳过所有负数可以使用continue语句来跳过当前迭代并开始下一个迭代。

for i = 1:length(A)    if A(i) < 0        continue    end    % 在这里编写处理非负元素的代码end
下面的例子是假设有一个矩阵A,需要在其中查找一个特定的值target,并且只需要找到它第一次出现的位置。这里使用了双重循环,对性能有较大影响,因此在这个例子中,可以使用break语句在找到目标值后立即中断双重循环

[m, n] = size(A);for i = 1:m    for j = 1:n        if A(i,j) == target            % 找到了目标值,记录位置并结束循环            row = i;            col = j;            break;        end    end    % 如果找到了目标值,退出循环    if exist('row', 'var') && exist('col', 'var')        break;    endend
但需要注意的是,在一些情况下,break 实际上会同时退出内部和外部循环,因为提前退出条件对于所有随后的外部循环迭代都成立。

02

将I/O操作推迟到循环结束

经常看到的的性能陷阱之一是在循环内执行I/O操作的代码。
相对于CPU而言,I/O的速度要慢上数千倍。在循环内进行I/O操作会使循环变慢。
如果I/O对于循环中的计算至关重要,我们可能别无选择。但通常情况下,输出是将计算结果输出到某个数据文件或日志的形式呈现。这种输出通常可以推迟到循环结束后再进行。
乍一看似乎由于相同的数据被写入磁盘,不应该有任何加速效果。然而,I/O工作方式是单次大规模更新比多次小规模更新更有效率。当使用xlswrite(或者writetable等函数)更新Excel工作表时尤其重要,因为每次调用xlswrite都会启动一个Excel进程、加载相关工作簿、更新它,并关闭工作簿和Excel进程。在循环中执行此操作对性能的损失是巨大的

例如:

data = magic(3); % 在循环中进行I/O操作ticfor col = 1 : size(data,2)    for row = 1 : size(data,1)        cellAddr = ['A'+col-1 '1'+row-1];        range = [cellAddr ':' cellAddr];        xlswrite('test.xls',data(row,col),range);    endendt1 = toc

将循环优化为:

lastCellAddr = ['A'+size(data,1)-1 '1'+size(data,2)-1];range = ['A1:' lastCellAddr];xlswrite('test.xls',data,range);

速度可提升8x以上。

03

简化重复引用

访问对象属性/方法、数组元素和结构字段会产生运行时处理开销(包括边界和安全检查)。
根据使用频率、循环大小和平均迭代运行时间,这种时间开销可能是循环总运行时间的重要部分。
将此类间接数据访问缓存到简单变量中可以消除这种性能损失,并且通常可以带来重要的加速效果
例如:
% 简单的循环用于访问数组元素a = [0,0];for idx = 1 : 1e8    a(2) = a(2) + idx;end
% 对上述循环使用一个临时累加器可以提高性能a = [0,0];b = 0;for idx = 1 : 1e8 b = b + idx; % b instead of a(2)enda(2) = b;b;

简化重复引用适用于任何数据类型,包括元胞数组(如c{1}{2,3}(4))。

同样,在访问结构、表或类对象字段时:

% 更新结构数组示例for idx = 1 : 1e6    a(3).b(2,3).c(4).d = rand(1);end
% 使用临时变量val替换结构数组a(3).b(2,3).c(4).d,可以提高性能for idx = 1 : 1e6 val = rand(1); enda(3).b(2,3).c(4).d = val;
% 检索结构数组示例for idx = 1 : 1e6 val = a(3).b(2,3).c(4).d * rand(1);end
% 通过v替代数组a(3).b(2,3).c(4).d,可以提高性能v = a(3).b(2,3).c(4).d;for idx = 1 : 1e6 val = v*rand(1); end

—— end ——

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
MATLAB标准性能优化技术 — 循环优化(1)
MATLAB GPU编程基础
链表
android开发性能优化总结
Web性能优化系列:10个JavaScript性能提升的技巧
python中使用矢量化替换循环
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服