【发布时间】:2013-08-19 00:47:58
【问题描述】:
在 MATLAB 中高效编程学习的第一件事是避免动态调整数组大小。标准示例如下。
N = 1000;
% Method 0: Bad
clear a
for i=1:N
a(i) = cos(i);
end
% Method 1: Better
clear a; a = zeros(N,1);
for i=1:N
a(i) = cos(i)
end
这里的“坏”变体需要 O(N^2) 时间来运行,因为它必须在循环的每次迭代中分配一个新数组并复制旧值。
我自己在调试时的首选做法是使用NaN 分配一个数组,这比0 更难与有效值混淆。
% Method 2: Easier to Debug
clear a; a = NaN(N,1);
for i=1:N
a(i) = cos(i)
end
然而,有人会天真地认为,一旦我们的代码被调试,我们分配一个数组然后用0 或NaN 填充它是在浪费时间。如here 所述,您也许可以创建一个未初始化的数组,如下所示
% Method 3 : Even Better?
clear a; a(N,1) = 0;
for i=1:N
a(i) = cos(i);
end
但是,在我自己的测试 (MATLAB R2013a) 中,我注意到方法 1 和 3 之间没有明显区别,而方法 2 需要更多时间。这表明 MATLAB 避免在调用 a = zeros(N,1) 时将数组显式初始化为零。
所以我很想知道
- 在 MATLAB 中预分配(未初始化的)数组的最佳方法是什么? (最重要的是,大型数组)
- 这在 Octave 中也成立吗?
【问题讨论】:
-
这很有趣。我想也许 MATLAB 在修改矩阵之前没有初始化零(类似于 matlab 复制矩阵的方式),但在我的机器上,
tic; a = NaN(1e4); a(1) = 1; toc确实比tic; a = zeros(1e4); a(1) = 1; toc慢。不过提醒一下,我真的只看到过使用zeros完成的预分配,所以我很确定除非你要创建一个 mex 例程,否则没有办法在没有初始化的情况下进行预分配,但也许这里的其他人会知道. -
这正在迅速成为一个 Matlab 常见问题解答,并且该问题的各个方面已经在 SO 上进行了介绍。在其他地方也是如此,例如在非常宝贵的 Undocumented Matlab 博客上 --undocumentedmatlab.com/blog/allocation-performance-take-2/… 随着 Matlab 的发展,各种方法的比较速度似乎发生了变化。
-
@Shai 这是关于预分配方法的性能,而不是关于预分配的需要。请停止关闭这样的问题。
-
@EJG89 我觉得这些问题已经足够接近,足以证明“关闭为 dup”是合理的。我理解你不同意我的观点,这很好。对于此类分歧,可以选择重新投票。非常欢迎您投票支持重新开放。
-
够近了吗?内存预分配的不同方式及其性能与内存预分配的需要有何不同。讨论处于更高级的水平,我只是不明白为什么你会如此草率地结束问题。我可能没有代表投票支持重新开放,所以你似乎只是在自己玩。您似乎只是不希望人们讨论 MatLab 的更深层/内部工作。我认为另一个主题甚至没有触及 JIT,而这是这个问题的基础。
标签: matlab memory-management octave