Cellfun versus Simple Matlab Loop performance

后端 未结 4 1598
挽巷
挽巷 2020-11-27 19:41

When I started working with matlab sometime ago in the university, my supervisor would kill me if he saw any unnecessary for loop (he would ask for exchanging it for k

4条回答
  •  死守一世寂寞
    2020-11-27 20:18

    I will add one answer with the results that I tested myself, but I would be glad if people contribute with their knowledge, this is just a simple test I've made.

    I've tested the following conditions with cell size of 1000 and 1000 loops (results on total time, and I would probably have to run more than 1000 times, because I am having a little fluctuation on the results, but anyway, this is not a scientific article):

    • Basic operation (sum)
      • Simple for loop: 0.2663 s
      • cellfun: 9.4612 s
    • String Operation (strcmp)
      • Simple for loop: 1.3124 s
      • cellfun: 11.8099 s
    • Built-in (isempty)
      • Simple for loop: 8.9042 s
      • cellfun (string input -> see this reference): 0.0105 s
      • cellfun (fcn handle input -> see this reference): 0.9209 s
    • Non-uniform (regexp)
      • Simple for loop: 24.2157 s
      • cellfun (string input): 44.0424 s

    So, it seems that cellfun with anonymous function calls are slower than a simple for loop, but if you will use a builtin matlab method, do it with cellfun and use it with the string quotation. This is not necessarily true for all cases, but at least for the tested functions.

    The implemented test code (I am far from being an optimization specialist, so here is the code in case I did something wrong):

    function ...
      [loop_timeAdd,cellfun_timeAdd,...
      loop_timeStr,cellfun_timeStr,...
      loop_timeBuiltIn,cellfun_timeBuiltInStrInput,...
      cellfun_timeBuiltyInFcnHandle,...
      loop_timeNonUniform,cellfun_timeNonUniform] ...
      = test_cellfun(nTimes,nCells)
    
    myCell = repmat({0},1,nCells);
    output = zeros(1,nCells);
    
    % Basic operation
    tic;
    for k=1:nTimes
      for m=1:nCells
        output(m) = myCell{m} + 1;
      end
    end
    loop_timeAdd=toc;
    
    tic;
    for k=1:nTimes
      output = cellfun(@(in) in+1,myCell);
    end
    cellfun_timeAdd=toc;
    
    % String operation
    myCell = repmat({'matchStr'},1,nCells); % Add str that matches
    myCell(1:2:end) = {'dontMatchStr'}; % Add another str that doesnt match
    output = zeros(1,nCells);
    
    tic;
    for k=1:nTimes
      for m=1:nCells
        output(m) = strcmp(myCell{m},'matchStr');
      end
    end
    loop_timeStr=toc;
    
    tic;
    for k=1:nTimes
      output = cellfun(@(in) strcmp(in,'matchStr'),myCell);
    end
    cellfun_timeStr=toc;
    
    % Builtin function (isempty)
    myCell = cell(1,nCells); % Empty
    myCell(1:2:end) = {0}; % not empty
    output = zeros(1,nCells);
    
    tic;
    for k=1:nTimes
      for m=1:nCells
        output(m) = isempty(myCell{m});
      end
    end
    loop_timeBuiltIn=toc;
    
    tic;
    for k=1:nTimes
      output = cellfun(@isempty,myCell);
    end
    cellfun_timeBuiltyInFcnHandle=toc;
    
    tic;
    for k=1:nTimes
      output = cellfun('isempty',myCell);
    end
    cellfun_timeBuiltInStrInput=toc;
    
    % Builtin function (isempty)
    myCell = repmat({'John'},1,nCells);
    myCell(1:2:end) = {'Doe'};
    output = cell(1,nCells);
    
    tic;
    for k=1:nTimes
      for m=1:nCells
        output{m} = regexp(myCell{m},'John','match');
      end
    end
    loop_timeNonUniform=toc;
    
    tic;
    for k=1:nTimes
      output = cellfun(@(in) regexp(in,'John','match'),myCell,...
        'UniformOutput',false);
    end
    cellfun_timeNonUniform=toc;
    

提交回复
热议问题