Why accessing to table is slower than accessing to struct?
7 次查看(过去 30 天)
显示 更早的评论
Hi all,
I have a very large dataset of table data type with nested struct. I have carried out two scrips, one which deals with the table and the other with struct by converting the table into a struct (with the table2struct function). However, it seems that dealing with struct is much faster than dealing with the table. Below you will find a sample of my code. For most of the lines, there is no real difference between the two scripts, with the exception of the following that is inside a for-loop and therefore it significantly impacts on the overall script performance. Why such big difference? Is there a way to make it faster?
Sigs{iSig2Load(j)}(Pos2Paste)=single(messageStruct(i).Signals.(Sig{iSig(j)}));
Thank you,
Best regards.
SigNames={'s1','s2','s3','s4','s5'; 'a1','a1','a1','a2','a2'};
MessLength=40;
for i=1:2:MessLength
messageStruct(i).Name='a1';
messageStruct(i).Signals.s1=1;
messageStruct(i).Signals.s2=2;
messageStruct(i).Signals.s3=3;
end
for i=2:2:MessLength
messageStruct(i).Name='a2';
messageStruct(i).Signals.s4=4;
messageStruct(i).Signals.s5=5;
end
tic
UniqueMessFound=unique({messageStruct.Name});
UniqueMessageCount=countcats(categorical({messageStruct.Name},UniqueMessFound));
for iSig=1:length(SigNames(1,:))
Sigs{iSig}=NaN(UniqueMessageCount(strcmp(UniqueMessFound,SigNames{2,iSig})),1);
end
for i=1:MessLength
Sig=fieldnames(messageStruct(i).Signals);
[~,iSig2Load , iSig]=intersect(SigNames(1,:),Sig);
Sig2Sel=SigNames(1,iSig2Load);
for j=1:length(Sig2Sel)
Pos2Paste=find(isnan(Sigs{iSig2Load(j)}),1);
Sigs{iSig2Load(j)}(Pos2Paste)=single(messageStruct(i).Signals.(Sig{iSig(j)}));
end
end
toc
%%
SigNames={'s1','s2','s3','s4','s5'; 'a1','a1','a1','a2','a2'};
MessLength=40;
for i=1:2:MessLength
messageStruct(i).Name='a1';
messageStruct(i).Signals.s1=1;
messageStruct(i).Signals.s2=2;
messageStruct(i).Signals.s3=3;
end
for i=2:2:MessLength
messageStruct(i).Name='a2';
messageStruct(i).Signals.s4=4;
messageStruct(i).Signals.s5=5;
end
tic
message=struct2table(messageStruct);
UniqueMessFound=unique(message.Name);
UniqueMessageCount=countcats(categorical(message.Name,UniqueMessFound));
for iSig=1:length(SigNames(1,:))
Sigs{iSig}=NaN(UniqueMessageCount(strcmp(UniqueMessFound,SigNames{2,iSig})),1);
end
for i=1:MessLength
Sig=fieldnames(message.Signals{i});
[~,iSig2Load , iSig]=intersect(SigNames(1,:),Sig);
Sig2Sel=SigNames(1,iSig2Load);
for j=1:length(Sig2Sel)
Pos2Paste=find(isnan(Sigs{iSig2Load(j)}),1);
Sigs{iSig2Load(j)}(Pos2Paste)=single(message.Signals{i}.(Sig{iSig(j)}));
end
end
toc
0 个评论
回答(1 个)
Maadhav Akula
2019-10-24
So, I could see in your code that for the second time measurement you also included the line
message=struct2table(messageStruct);
for time measurement(tic -toc), which takes up a significant chunk of time to compute!
Even then, if you remove that line from time measurement(tic -toc), struct runs significantly faster than the table and this is expected behavior in your case as you are accessing each element of the table in a loop and accessing it is a little slow. But, accessing a variable in a table is not always slow. Accessing a "large enough" subset of rows of a variable is fast. But at some point if the subsets are small and computations surrounding them are very cheap, the table subscripting is going to dominate the time and it will look that table is slower.
So, I would suggest you convert the data into a struct(table2struct) and perform your operation and then convert the data back into table(struct2table).
Hope this helps!
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Data Type Conversion 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!