15 views (last 30 days)

Show older comments

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

Bruno Luong
on 28 Jul 2021

Matt J
on 28 Jul 2021

Walter Roberson
on 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

Walter Roberson
on 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.

Adam Danz
on 12 Aug 2021

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

Start Hunting!