对数组进行预分配后,​反而严重降低了赋值的​速度,请问如何解决?

数组预分配后,赋值操作反而需要更多的时间,矩阵的维度越大,预分配后进行赋值需要的时间更多。
注释掉预分配语句后,赋值时间减少
clearvars
test_h_matx_diag = zeros(1024,1024,360); % 预分配语句
h_matx = rand(1024,1,360);
h_matx = exp(-1j*2*pi*h_matx);
for ii = 1:size(h_matx,3)
temp1 = diag(h_matx(:,:,ii));
test_h_matx_diag(:,:,ii) = temp1; % 赋值的速度受预分配的影响
end

 Accepted Answer

埃博拉酱
埃博拉酱 on 26 Oct 2024
Edited: 埃博拉酱 on 26 Oct 2024

0 votes

我测试的结果是预分配7秒,不预分配11秒,并没有出现预分配反而更慢的问题。
你是否在进行不预分配的测试之前,忘记了清空上次预分配测试后残余的变量?
另外,这样做更快,只要2秒:
test_h_matx_diag = zeros(1024*1024,360); % 预分配语句
test_h_matx_diag(1:1025:end,:)=exp(-1j*2*pi*rand(1024,360));
test_h_matx_diag=reshape(test_h_matx_diag,1024,1024,360);

3 Comments

嘉俊
嘉俊 on 27 Oct 2024
Edited: 嘉俊 on 28 Oct 2024
我测试了完整的for循环时间,发现确实如你所说。非常感谢你的回答,学习了。
我之前只在测试一次赋值所需的时间,现在我完整地测试了所有for循环的时间,发现取消预分配仅仅在第一轮for循环的赋值中有速度优势,完整的时间是更长的。具体结果如下:
进行预分配后的完整循环时间:
不进行预分配的完整循环时间:
----------------------------------------------------------------------------------------
以下为旧回复,我发现我错误的地方了
非常感谢你的回复,我正在学习你的reshape方法。
测试之前我添加了clearvars命令,但是忘了打出来了,题目已改正。
不知道为什么你的测试结果与我不同,我的测试结果如下图所示:
进行预分配:
不进行预分配:
埃博拉酱
埃博拉酱 on 27 Oct 2024
Edited: 埃博拉酱 on 27 Oct 2024
据我猜测,预分配语句本身并不会立即向操作系统申请内存,而是延迟到第一次修改该数组时,因此第一次循环的时间实际上还包括了真正的预分配操作时间,但后续就不用再分配了。而不预分配的情况在第一次循环时申请的内存比预分配的少,所以会更快,但是后续循环每次都要分配更多内存,所以总体比预分配的慢。 你可以用任务管理器监控MATLAB的内存占用看看是否是这样。
嘉俊
嘉俊 on 28 Oct 2024
Edited: 嘉俊 on 28 Oct 2024
确实是这样的,使用预分配语句后,在第一次循环的赋值中,内存占用一直在上涨,我甚至以为哪里出错导致内存泄漏了(lll¬ω¬),吓坏我了(*Φ皿Φ*)。因为原代码中,第三维为2160,每次程序运行到这里就不动弹了,我一度以为死循环了。我重新写了个小测试维度采用360才发现原来不是卡死(也就是本问题题目代中的码),是赋值语句占用时间太多了(lll¬ω¬)

Sign in to comment.

More Answers (0)

Categories

Find more on 性能和内存 in Help Center and File Exchange

Products

Release

R2024a

Tags

Asked:

on 26 Oct 2024

Edited:

on 28 Oct 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!