罗兰在MATLAB的艺术

把想法变成MATLAB

请注意

罗兰在MATLAB的艺术已经存档,不会被更新。

一劳永逸地

我是跟我的长期的同事,迈克·裘槎加入MathWorks团队最近(耶!)。关于一些有趣的话题,其中一些可能一篇博客文章的好饲料。今天我想谈谈循环。

嵌套循环

在我的旧的Fortran编程天(是的,长了),我认识到早期代码跑得更快,如果我安排我的嵌套对- - - - - -循环优化。在Fortran,如果我是计算矩阵的一个元素,这意味着确保我填充顺序的元素,这意味着循环在每一行1列,因为这就是Fortran (MATLAB)存储阵列。这不是如何存储在C数组。
我今天在MATLAB很好奇发生了什么如果我尝试运行嵌套循环在不同的订单。让我们看看!
让我们计算Ar, c = r * (r + c3) + 17

解决方案直接循环,内循环的行

当然我preallocate输出数组,基于“增大化现实”技术
t = 0 (1、3);
n = 1000;
抽搐;
基于“增大化现实”技术= 0 (n, n);
[nrows, ncolumns] =大小(Ar);
行= 1:nrows
列= 1:ncolumns
基于“增大化现实”技术(行、列)=行*(行+列^ 3)+ 17;
结束
结束
t (1) = toc;

解决方案直接循环,内循环列

现在另一个订单。
抽搐;
Ac = 0 (n, n);
[nrows, ncolumns] = (Ac)大小;
列= 1:ncolumns
行= 1:nrows
交流(行、列)=行*(行+列^ 3)+ 17;
结束
结束
t (2) = toc;

矢量化的解决方案

当然,矢量化版本。
抽搐;
tmpr = (1: nrows)。';
Av = tmpr。* (tmpr + (1: ncolumns)。^ 3) + 17;
t (3) = toc;

分析

让我们确保他们也产生相同的结果。
areAnswerEqual = isequal (Ac, Ar, Av)
areAnswerEqual =逻辑
1
和执行时间呢?
t
t = 1×3
0.1236 0.0190 0.0082

顺序很重要

在MATLAB,使用嵌套循环,明显的顺序循环问题从时间的角度来看。所以它是明智的命令他们知道数据存储列的列,如果你可以写你的算法。我没有显示效果可能是如果我们不preallocate输出矩阵。你可以试着自己。
尽管得到了很好的加速通过争吵嵌套循环,它仍然是通常更可取的,从速度的角度来看,尝试对代码进行向量化。注意,我使用隐式的扩张来计算Av。还要注意,你不会总是相同的速度比循环和等效矢量化版本之间的区别——它将在很大程度上取决于有多少工作进行了计算和产生多大的开销。

你的想法呢?

当使用MATLAB循环中,从速度的角度,最好是如果你可以设置循环元素是尽可能接近顺序访问。你可以看到从上面的小例子,运行列行提供优越的性能与运行。这是由于MATLAB存储阵列。
你遇到一个情况重新排序循环帮助你吗?让我们知道在这里
版权2021年MathWorks公司。

评论

留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。