在Matlab中提高函数调用的速度

时间:2012-12-19 07:16:36

标签: performance function matlab call

我的代码带有一个调用函数,它给出了系统中每个基因的类型。我可以通过比较每个基因与其子女和父母的顺序来找到它。代码工作正常,有一小部分单元格阵列,但当我将数量增加到数千时,需要几个小时。代码是:

Types=[];
type1=level1_root; % it is fixed value (GO:0008150)
% sample values for p1 and c1 are given below
for k=1:100
    type{k}=type_fc(p1,c1,type1); % a function call - see function below
    type1=type{k}'; %'
    temp1=num2cell(repmat(k+1,length(type1),1));
    type1=[type1 temp1];
    Types=[Types; type1];
 end
 % display the output:
 Types

子功能:

function type=type_fc(p1,c1,type1)
type=[];
for j=1:length(type1)
    for i=1:length(p1)
        a=[p1(i),c1(i)];
        if isequal(a(1), type1(j))
            type=[type a(2)];
        end
    end
end

对于13个基因,我有这些样本输入:

p1'= %refer to parent genes  
      'GO:0008150'
      'GO:0016740'
      'GO:0016787'
      'GO:0008150'
      'GO:0016740'
      'GO:0016740'
      'GO:0016787'
      'GO:0016787'
      'GO:0016787'
      'GO:0006810'
      'GO:0006412'
      'GO:0004672'


 c1'=  % refer to children genes    
  'GO:0016740'
  'GO:0016787'
  'GO:0006810'
  'GO:0006412'
  'GO:0004672'
  'GO:0016779'
  'GO:0004386'
  'GO:0003774'
  'GO:0016298'
  'GO:0016192'
  'GO:0005215'
  'GO:0030533'

结果将是:Types =

  'GO:0016740'    [2]
  'GO:0006412'    [2]
  'GO:0016787'    [3]
  'GO:0004672'    [3]
  'GO:0016779'    [3]
  'GO:0005215'    [3]
  'GO:0006810'    [4]
  'GO:0004386'    [4]
  'GO:0003774'    [4]
  'GO:0016298'    [4]
  'GO:0030533'    [4]
  'GO:0016192'    [5]

您是否知道如何提高此代码的速度?

2 个答案:

答案 0 :(得分:7)

乍一看,我可以在您的代码中发现一些问题:

  1. 首先,Typestype在循环内动态增长。就执行时间而言,这在MATLAB中可能非常昂贵。相反,在循环之前预先分配内存(即,使用预定的最终元素数创建数组),您可能会看到性能的显着提升。

  2. 你正在使用循环。如果有一个矢量化解决方案(我还没有检查过),计算时间可能会少得多。

  3. 您使用ij索引作为循环迭代器的变量名称。这些变量已经有另一个目的:它们代表虚构单位sqrt(-1)。 MATLAB仍允许使用ij作为变量名,但为了找出正确的上下文,它所做的变量名称解析确实需要很少的成本。您应该选择其他名称,甚至是iijj 编辑:同样适用于type,它在MATLAB中已经是reserved function name

  4. 尝试以下优化版本,它应该运行至少一个数量级:

    Types = cell(numel(c1), 2);      % # Preallocate memory
    type1 = level1_root;             % # ... or p1{1}
    kk = [1, 2];                     % # Initialize indices
    while ~isempty(type1)
        type_fc = cellfun(@(x)c1(strcmp(x, p1)), type1, 'Uniform', false);
        type1 = vertcat(type_fc{:});
        idx = kk(1):kk(1) + numel(type1) - 1;
        Types(idx, 1) = type1;
        Types(idx, 2) = {kk(2)};
        kk = kk + [numel(type1), 1]; % # Advance indices
    end
    Types = Types(1:kk(1) - 1, :);   % # Remove empty output cells
    

答案 1 :(得分:2)

如果我正确读取它,那么该函数将类型1中的值与p1中的父基因进行比较,在那里找到匹配,然后从c1返回相应的子基因。这是对的吗?

在这种情况下,矢量化解决方案使用 strcmp 来获取type1(j)和p1之间匹配的逻辑数组。

>> strcmp(type1(j),p1)

然后可以将其用于数组c1上的逻辑寻址,实际上它是来自要提取的c1的值的真值表。我假设你正在处理这些作为单元格数组,在这种情况下我认为这样的东西应该工作。

function type=type_fc(p1,c1,type1)
type={};
for j=1:length(type1)
    type=[type{:} c1(strcmp(type1(j),p1))'];
end

现在是否让它更快我不确定,我希望你能测试它。这是我对“矢量化”解决方案的建议。