问题
I want to concatenate along the third dimension
z = cat(3,A,B,C);
Many many times. I if I was doing that along the second dimension then
z = [A,B,C];
Would be faster than
z = cat(2,A,B,C);
Can a similar thing be done along the third dimension or is there any other way to speed this up?
回答1:
There are some indexing options to get a slightly better performance than cat(3,...).
Both solutions use U(30,30,3)=0; instead of zeros(30,30,3) to preallocate, but it is unsave as it will result in a subscript dimension missmatch when U is already a variable of a larger size.
The first option is to assign the different slices individually.
%fast but unsafe preallocation
U(30,30,3)=0;
%robust alternative:
%U=zeros(30,30,3)
U(:,:,3)=C;
U(:,:,1)=A;
U(:,:,2)=B;
The second option is to use linear indexing. For z1 = cat(3,A,B,C); and z2=[A;B;C] it is true that z1(:)==z2(:)
%fast but unsafe preallocation
U(30,30,3)=0;
%robust alternative:
%U=zeros(30,30,3)
U(:)=[A,B,C];
I benchmarked the solutions, comparing it to cat(3,A,B,C) and [A,B,C]. The linear indexing solution is only slightly slower than [A,B,C].
0.392289 s for 2D CAT
0.476525 s for Assign slices
0.588346 s for cat(3...)
0.392703 s for linear indexing
Code for benchmarking:
N=30;
A=randn(N,N);
B=randn(N,N);
C=randn(N,N);
T=containers.Map;
cycles=10^5;
tic;
for i=1:cycles
W=[A;B;C];
X=W+1;
end
T('2D CAT')=toc;
tic;
for i=1:cycles
W=cat(3,A,B,C);
X=W+1;
end
T('cat(3...)')=toc;
U=zeros(N,N,3);
tic;
for i=1:cycles
U(N,N,3)=0;
U(:,:,3)=C;
U(:,:,1)=A;
U(:,:,2)=B;
V=U+1;
end
T('Assign slices')=toc;
tic;
for i=1:cycles
U(N,N,3)=0;
U(:)=[A,B,C];
V=U+1;
end
T('linear indexing')=toc;
for X=T.keys
fprintf('%f s for %s\n',T(X{1}),X{1})
end
来源:https://stackoverflow.com/questions/33761451/is-there-a-way-to-speed-up-concatenation-in-matlab