Fast alternative to assign 0 to NaNs
5 次查看(过去 30 天)
显示 更早的评论
Hi all,
is there a astest way to assign to zeros the value NaN? From the Profiler I am noticing that this operation is taking more than a second in my code and would like it to be fastest.
I have some inefficiencies in the code (e.g. the fact that there are several for loop rather a unique one). Here is my code and where I would like it to be faster:
for i = 1:N_RIPETIZIONI
for j = 1:size(colonna_i,2)
%MATRICI_SIMULATE_nonan{i,j}=MATRICI_SIMULATE{i,j}.*A_nan;
MATRICI_SIMULATE_nonan{i,j}(MATRICI_SIMULATE_nonan{i,j} == 0) = NaN; %%here
end
end
MATRICI_SIMULATE_DUMMY = cell(N_RIPETIZIONI,size(colonna_i,2));
for i = 1:N_RIPETIZIONI
for j = 1:size(colonna_i,2)
%MATRICI_SIMULATE_DUMMY{i,j}=double(MATRICI_SIMULATE_DUMMY{i,j});
MATRICI_SIMULATE_DUMMY{i,j}(A_nan == 0) = NaN; %%here
end
end
Is this slowing up in speedd the result of the fact that I am operating with cell arrays? That I am operating in different for loops?
Thank you
3 个评论
Matt J
2022-12-17
I agree with Stephen. Based on what you've shown us, it is not clear why your matrices are split into cells, when they could easily be a 3D array.
回答(2 个)
Walter Roberson
2022-12-17
Asking about the fastest way to do something is almost always a mistake.
Suppose that the fastest way to do this particular sequence involved making sure that each of the cell contents is aligned in memory on a 4 Kb physical boundary, and using exactly 8 simultaneous cores. So you rewrite your code with a bunch of mex calls to ensure that memory is allocated the way you want (asking for aligned memory requires an operating-system-specific call but you need to use the MATLAB-supplied memory allocator routines...) And you test it all out, and after only three weeks of performance improvement work, you have saved at least 17 clock cycles in your calculation.
And then you go to run the code in real life... and your system goes to check email and you lose access to one of the 8 cores... and your code ends up taking 29 cycles longer than it otherwise would have.
And then you hand the code over to someone else, and on their system, your carefully tuned fastest code is always slower than the alternatives. Because to get the fastest code you had to take advantage of the exact microcode timings of the various instructions, and on their system the fine details of the microcode timing are slightly different and a cycle is lost each iteration instead of gaining a cycle.
Going for the fastest possible version of something is almost always a net loss (unless you are a chip manufacturer and getting the highest possible calculation rate is terribly important for advertising purposes.)
2 个评论
Walter Roberson
2022-12-19
You need to question any time you use a superlative such as "fastest" or "most" efficient. How do you measure efficiency? How do you handle the fact that making one aspect better might make another aspect worse?
Jan
2022-12-17
编辑:Jan
2022-12-17
Avoid calculate A_nan==0 repeatedly inside the loop. Do this once before the loop:
C = cell(10, 119);
for iC = 1:numel(C)
C{iC} = rand(1229, 222);
end
A = randi([0,1], 1229, 222);
tic; % Original version:
A_nan = (A ~= 0);
D = cell(size(C));
for i1 = 1:10
for i2 = 1:119
tmp = C{i1, i2};
tmp(A_nan == 0) = NaN;
D{i1, i2} = tmp;
end
end
toc
tic; % Move A_nan==0 out of the loop:
A_nan = (A == 0); % A==0 instead of A~=0
D = cell(size(C));
for i1 = 1:10
for i2 = 1:119
tmp = C{i1, i2};
tmp(A_nan) = NaN; % A_nan instead of A_nan==0
D{i1, i2} = tmp;
end
end
toc
As suggested already, the masking is much faster, if you work with a [10 x 119 x 1229 x 222] array.
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!