Search code examples
performancematlabcell-array

Faster concatenation of cell arrays of different sizes


I have a cell array of size m x 1 and each cell is again s x t cell array (size varies). I would like to concatenate vertically. The code is as follows:

function(cell_out) = vert_cat(cell_in)
    [row,col] = cellfun(@size,cell_in,'Uni',0);
    fcn_vert = @(x)([x,repmat({''},size(x,1),max(cell2mat(col))-size(x,2))]);
    cell_out = cellfun(fcn_vert,cell_in,'Uni',0); % Taking up lot of time
    cell_out = vertcat(cell_out{:});
end

Step 3 takes a lot of time. Is it the right way to do or is there any another faster way to achieve this?


Solution

  • I used this pice of code to generate data:

    %generating some dummy data
    m=1000;
    s=100;
    t=100;
    cell_in=cell(m,1);
    for idx=1:m
        cell_in{idx}=cell(randi(s),randi(t));
    end
    

    Applying some minor modifications, I was able to speed up the code by a factor of 5

    %Minor modifications of the original code
        %use arrays instead of cells for row and col
        [row,col] = cellfun(@size,cell_in);
        %claculate max(col) once
        tcol=max(col);
        %use cell instead of repmat to generate an empty cell
        fcn_vert = @(x)([x,cell(size(x,1),tcol-size(x,2))]);
        cell_out = cellfun(fcn_vert,cell_in,'Uni',0); % Taking up lot of time
        cell_out = vertcat(cell_out{:});
    

    Using simply a for loop is even faster, because the data is only moved once

    %new approac. Basic idea: move every data only once
        [row,col] = cellfun(@size,cell_in);
        trow=sum(row);
        tcol=max(col);
        r=1;
        cell_out2 = cell(trow,tcol);
        for idx=1:numel(cell_in)
            cell_out2(r:r+row(idx)-1,1:col(idx))=cell_in{idx};
            r=r+row(idx);
        end