Performance 加速代码以比较结构中的字段
我有字段uniqueDate、dateAll、label的结构轨迹:我想比较字段uniqueDate和dateAll,如果有对应关系,我会在label中保存另一个结构的值 我编写了以下代码:Performance 加速代码以比较结构中的字段,performance,matlab,struct,Performance,Matlab,Struct,我有字段uniqueDate、dateAll、label的结构轨迹:我想比较字段uniqueDate和dateAll,如果有对应关系,我会在label中保存另一个结构的值 我编写了以下代码: for k=1:nCols for j=1:size(Trajectories(1,k).dateAll,1) for i=1:size(Trajectories(1,k).uniqueDate,1) if (~isempty(s(1,k).places))&
for k=1:nCols
for j=1:size(Trajectories(1,k).dateAll,1)
for i=1:size(Trajectories(1,k).uniqueDate,1)
if (~isempty(s(1,k).places))&&(Trajectories(1,k).dateAll(j,1)==Trajectories(1,k).uniqueDate(i,1))&&(Trajectories(1,k).dateAll(j,2)==Trajectories(1,k).uniqueDate(i,2))&&(Trajectories(1,k).dateAll(j,3)==Trajectories(1,k).uniqueDate(i,3))
for z=1:24
if(Trajectories(1,k).dateAll(j,4)==z)&&(size(s(1,k).places.all,2)>=size(Trajectories(1,k).uniqueDate,1))
Trajectories(1,k).label(j)=s(1,k).places.all(z,i);
else if(Trajectories(1,k).dateAll(j,4)==z)&&(size(s(1,k).places.all,2)<size(Trajectories(1,k).uniqueDate,1))
for l=1:size(s(1,k).places.all,2)
Trajectories(1,k).label(l)=s(1,k).places.all(z,l);
end
end
end
end
end
end
end
end
它能跑,但速度很慢。我如何修改它以加快速度?让我们从内到外工作,看看它能给我们带来什么 步骤1:简化比较条件:
if (~isempty(s(1,k).places))&&(Trajectories(1,k).dateAll(j,1)==Trajectories(1,k).uniqueDate(i,1))&&(Trajectories(1,k).dateAll(j,2)==Trajectories(1,k).uniqueDate(i,2))&&(Trajectories(1,k).dateAll(j,3)==Trajectories(1,k).uniqueDate(i,3))
变成
if (~isempty(s(1,k).places)) && all( Trajectories(1,k).dateAll(j,1:3)==Trajectories(1,k).uniqueDate(i,1:3) )
然后我们要从for循环中删除它。“intersect”函数在这里很有用:
[ia i1 i2]=intersect(Trajectories(1,k).dateAll(:,1:3),Trajectories(1,k).uniqueDate(:,1:3),'rows');
现在我们有了一个向量i1
,它包含了dateAll
中与uniqueDate
相交的所有行
现在,我们可以使用类似的方法删除比较z
的循环:
[iz iz1 iz2] = intersect(Trajectories(1,k).dateAll(i1,4),1:24);
在这里,我们必须小心我们的索引,使用子集的子集
这将代码简化为:
for k=1:nCols
if isempty(s(1,k).places)
continue; % skip to the next value of k, no need to do the rest of the comparison
end
[ia i1 i2]=intersect(Trajectories(1,k).dateAll(:,1:3),Trajectories(1,k).uniqueDate(:,1:3),'rows');
[iz iz1 iz2] = intersect(Trajectories(1,k).dateAll(i1,4),1:24);
usescalarlabel = (size(s(1,k).places.all,2)>=size(Trajectories(1,k).uniqueDate,1);
if (usescalarlabel)
Trajectories(1,k).label(i1(iz1)) = s(1,k).places.all(iz,i2(iz1));
else
% you will need to check this: I think here you were needlessly repeating this step for every match
Trajectories(1,k).label(i1(iz1)) = s(1,k).places.all(iz,:);
end
end
但是等等!z循环与使用索引完全相同。所以我们不需要第二个交叉点:
for k=1:nCols
if isempty(s(1,k).places)
continue; % skip to the next value of k, no need to do the rest of the comparison
end
[ia i1 i2]=intersect(Trajectories(1,k).dateAll(:,1:3),Trajectories(1,k).uniqueDate(:,1:3),'rows');
usescalarlabel = (size(s(1,k).places.all,2)>=size(Trajectories(1,k).uniqueDate,1);
label_indices = Trajectories(1,k).dateAll(i1,4);
if (usescalarlabel)
Trajectories(1,k).label(label_indices) = s(1,k).places.all(label_indices,i2);
else
% you will need to check this: I think here you were needlessly repeating this step for every match
Trajectories(1,k).label(label_indices) = s(1,k).places.all(label_indices,:);
end
end
你需要在这里检查索引-我肯定我在没有数据可供测试的地方犯了一个错误,但这应该会让你知道如何继续删除循环并使用向量表达式。没有看到我能优化的数据。如果您可以将数据重新格式化为一组3d矩阵/单元格,而不是使用结构,那么您可能可以更进一步
我怀疑您的情况,我称之为“usescalarlabel”-似乎您混合了两种数据类型。此外,我强烈建议将dateAll矩阵分为单独的“日期”和“数据”矩阵,因为第4行之后的索引似乎不是日期。另外,您复制/粘贴的示例在行索引1处似乎有一个额外的值?在这种情况下,您需要比较轨迹(1,k).dateAll(:,2:4)
而不是轨迹(1,k).dateAll(:,1:3)
祝你好运。Puuh,也许可以给我们一小部分输入数据(如果可能的话,通过MATLAB生成数据,这样我们就可以轻松地自己尝试了)。我的第一个想法是重新思考整个数据布局。也许使用几个单独的矩阵比使用一个大的结构更容易。
for k=1:nCols
if isempty(s(1,k).places)
continue; % skip to the next value of k, no need to do the rest of the comparison
end
[ia i1 i2]=intersect(Trajectories(1,k).dateAll(:,1:3),Trajectories(1,k).uniqueDate(:,1:3),'rows');
usescalarlabel = (size(s(1,k).places.all,2)>=size(Trajectories(1,k).uniqueDate,1);
label_indices = Trajectories(1,k).dateAll(i1,4);
if (usescalarlabel)
Trajectories(1,k).label(label_indices) = s(1,k).places.all(label_indices,i2);
else
% you will need to check this: I think here you were needlessly repeating this step for every match
Trajectories(1,k).label(label_indices) = s(1,k).places.all(label_indices,:);
end
end