Why is x(:) so much slower than reshape(x,N,1) with complex arrays?
11 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
The two for loops below differ only in the flattening operation used to obtain A_1D . Why is the run time so much worse with A_3D(:) than with a call to reshape()?
Nx = 256;
Ny = 256;
Nz = 128;
N = Nx*Ny*Nz;
A0 = rand(N,1);
tic
for k = 1:20
B = reshape( A0, [Nz,Ny,Nx] ) ;
A_3D = fftn(B);
A_1D = reshape( A_3D, N,1); %<--- Version 1
end
toc
tic
for k = 1:20
B = reshape( A0, [Nz,Ny,Nx] ) ;
A_3D = fftn(B);
A_1D = A_3D(:); %<--- Version 2
end
toc
7 Kommentare
Bruno Luong
am 28 Jul. 2021
I must admit that understanding why/when MATLAB make data copy become obscure to me since few years now. I did not come to a full understanding of how it works.
Akzeptierte Antwort
Matt J
am 28 Jul. 2021
8 Kommentare
G A
am 14 Aug. 2021
Walter, I am discussing complex valued arrays, it can be
max(A,[],'all')
but anyway for a complex number max(A) = max(abs(A))
Walter Roberson
am 14 Aug. 2021
The (:) options are the slowest. reshape(abs(A),N,1) might possibly be the fastest -- there is notable variation in different runs.
Nx = 256;
Ny = 256;
Nz = 128;
N = Nx*Ny*Nz;
A0 = complex(randn(Nx, Ny, Nz), randn(Nx, Ny, Nz));
t(1) = timeit(@() use_abs_all(A0, N), 0)
t(2) = timeit(@() use_abs_colon(A0, N), 0)
t(3) = timeit(@() use_abs_reshape_null(A0, N), 0)
t(4) = timeit(@() use_abs_reshape_N(A0, N), 0)
t(5) = timeit(@() use_all(A0, N), 0)
t(6) = timeit(@() use_colon(A0, N), 0)
t(7) = timeit(@() use_reshape_null(A0, N), 0)
t(8) = timeit(@() use_reshape_N(A0, N), 0)
cats = categorical({'abs(all)', 'abs(:)', 'reshape(abs,[])','reshape(abs,N)', 'all', '(:)', 'reshape([])', 'reshape(N)'});
bar(cats, t)
function B = use_abs_all(A, N)
B = max(abs(A), [], 'all');
end
function B = use_abs_colon(A, N)
B = max(abs(A(:)));
end
function B = use_abs_reshape_null(A, N)
B = max(reshape(abs(A), [], 1));
end
function B = use_abs_reshape_N(A, N)
B = max(reshape(abs(A), N, 1));
end
function B = use_all(A, N)
B = max(A, [], 'all');
end
function B = use_colon(A, N)
B = max(A(:));
end
function B = use_reshape_null(A, N)
B = max(reshape(A, [], 1));
end
function B = use_reshape_N(A, N)
B = max(reshape(A, N, 1));
end
Weitere Antworten (2)
Walter Roberson
am 28 Jul. 2021
Nx = 256;
Ny = 256;
Nz = 128;
N = Nx*Ny*Nz;
A0 = rand(Nx, Ny, Nz);
timeit(@() use_colon(A0, N), 0)
timeit(@() use_reshape_null(A0, N), 0)
timeit(@() use_reshape_N(A0, N), 0)
function use_colon(A, N)
B = A(:);
end
function use_reshape_null(A, N)
B = reshape(A, [], 1);
end
function use_reshape_N(A, N)
B = reshape(A, N, 1);
end
In this particular test, the timing is close enough that we can speculate some reasons:
Using an explicit size to reshape to is faster than reshape([]) because reshape([]) has to spend time calculating the size based upon dividing numel() by the size of the known parameters.
Using (:) versus reshape() is not immediately as clear. The model for (:) is that it invokes subsref() with struct('type', {'()'}, 'subs', {':'}) and then subsref() has to invoke reshape() . I point out "model" because potentially the Execution Engine could optimize all of this, and one would tend to think that optimization of (:) should be especially good.
10 Kommentare
Walter Roberson
am 11 Aug. 2021
I had the hypothesis that the 5 might have to do with my having 4 cores, or might have to do with the number of priming iterations I did, so I tested on my system that has more cores, and I did more priming iterations. The result was the same: duration(1,1) still had the major peak, and duration(5,1) was reliably a seconary peak.
Adam Danz
am 12 Aug. 2021
I noticed that when I re-run it within a script without clearing variables, the second peak at x=5 vanishes. Still curious but out of ideas.
Siehe auch
Kategorien
Mehr zu Loops and Conditional Statements finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!