Mat*_*tal 6 performance matlab large-data bigdata data-structures
我需要处理大量混合类型的表格数据 - 字符串和双精度数据.我想是一个标准问题.Matlab中用于处理此问题的最佳数据结构是什么?
Cellarray肯定不是答案.它的内存效率极低.(测试如下所示).数据集(来自统计工具箱)的时间和空间非常低效.这留下了structarray或数组结构.我在下面对时间和内存的所有四个不同选项进行了测试,在我看来,数组的结构是我测试的东西的最佳选择.
我对Matlab相对较新,坦率地说这有点令人失望.无论如何 - 寻找关于我是否遗漏某些东西,或者我的测试是否准确/合理的建议.除了访问/转换/内存使用之外,我还缺少其他注意事项,因为我使用这些东西编写代码更多.(我正在使用R2010b)
**测试#1:访问速度访问数据项.
cellarray:0.002s
dataset:36.665s %<<< This is horrible
structarray:0.001s
struct of array:0.000s
Run Code Online (Sandbox Code Playgroud)
**测试#2:转换速度和内存使用情况我从此测试中删除了数据集.
Cellarray(doubles)->matrix:d->m: 0.865s
Cellarray(mixed)->structarray:c->sc: 0.268s
Cellarray(doubles)->structarray:d->sd: 0.430s
Cellarray(mixed)->struct of arrays:c->sac: 0.361s
Cellarray(doubles)->struct of arrays:d->sad: 0.887s
Name Size Bytes Class Attributes
c 100000x10 68000000 cell
d 100000x10 68000000 cell
m 100000x10 8000000 double
sac 1x1 38001240 struct
sad 1x1 8001240 struct
sc 100000x1 68000640 struct
sd 100000x1 68000640 struct
Run Code Online (Sandbox Code Playgroud)
==================代码:测试#1
%% cellarray
c = cell(100000,10);
c(:,[1,3,5,7,9]) = num2cell(zeros(100000,5));
c(:,[2,4,6,8,10]) = repmat( {'asdf'}, 100000, 5);
cols = strcat('Var', strtrim(cellstr(num2str((1:10)'))))';
te = tic;
for iii=1:1000
x = c(1234,5);
end
te = toc(te);
fprintf('cellarray:%0.3fs\n', te);
%% dataset
ds = dataset( { c, cols{:} } );
te = tic;
for iii=1:1000
x = ds(1234,5);
end
te = toc(te);
fprintf('dataset:%0.3fs\n', te);
%% structarray
s = cell2struct( c, cols, 2 );
te = tic;
for iii=1:1000
x = s(1234).Var5;
end
te = toc(te);
fprintf('structarray:%0.3fs\n', te);
%% struct of arrays
for iii=1:numel(cols)
if iii/2==floor(iii/2) % even => string
sac.(cols{iii}) = c(:,iii);
else
sac.(cols{iii}) = cell2mat(c(:,iii));
end
end
te = tic;
for iii=1:1000
x = sac.Var5(1234);
end
te = toc(te);
fprintf('struct of array:%0.3fs\n', te);
Run Code Online (Sandbox Code Playgroud)
==================代码:测试#2
%% cellarray
% c - cellarray containing mixed type
c = cell(100000,10);
c(:,[1,3,5,7,9]) = num2cell(zeros(100000,5));
c(:,[2,4,6,8,10]) = repmat( {'asdf'}, 100000, 5);
cols = strcat('Var', strtrim(cellstr(num2str((1:10)'))))';
% c - cellarray containing doubles only
d = num2cell( zeros( 100000, 10 ) );
%% matrix
% doubles only
te = tic;
m = cell2mat(d);
te = toc(te);
fprintf('Cellarray(doubles)->matrix:d->m: %0.3fs\n', te);
%% structarray
% mixed
te = tic;
sc = cell2struct( c, cols, 2 );
te = toc(te);
fprintf('Cellarray(mixed)->structarray:c->sc: %0.3fs\n', te);
% doubles
te = tic;
sd = cell2struct( d, cols, 2 );
te = toc(te);
fprintf('Cellarray(doubles)->structarray:d->sd: %0.3fs\n', te);
%% struct of arrays
% mixed
te = tic;
for iii=1:numel(cols)
if iii/2==floor(iii/2) % even => string
sac.(cols{iii}) = c(:,iii);
else
sac.(cols{iii}) = cell2mat(c(:,iii));
end
end
te = toc(te);
fprintf('Cellarray(mixed)->struct of arrays:c->sac: %0.3fs\n', te);
% doubles
te = tic;
for iii=1:numel(cols)
sad.(cols{iii}) = cell2mat(d(:,iii));
end
te = toc(te);
fprintf('Cellarray(doubles)->struct of arrays:d->sad: %0.3fs\n', te);
%%
clear iii cols te;
whos
Run Code Online (Sandbox Code Playgroud)
我想说,如果您需要管理大量数据,那么 MATLAB 并不是最佳选择。寻找合适的数据库并最终将所需的数据导入 MATLAB。
但是,如果您打算使用 MATLAB,我仍然会选择cellarrays,也就是说,如果您不需要像结构体那样以字段名的形式对数据进行语法引用。
使用单元数组时,请记住每个单元会产生 112 字节的开销。因此,我将为每列创建一个单元格(而不是为每个标量双精度数创建一个单元格):
c = cell(1,10);
c(1,1:2:10) = num2cell(rand(1e5,5),1);
c(1,2:2:10) = {cellstr(repmat('asdf', 100000, 1))};
Run Code Online (Sandbox Code Playgroud)
和记忆方面(时间没有变化):
Name Size Bytes Class Attributes
c 1x10 38000600 cell
Run Code Online (Sandbox Code Playgroud)
此外,您所说的数组结构通常是指“标量”结构,而不是结构数组(或非标量结构)。
如果我没记错的话,当您开始嵌套字段时,结构的读/写性能往往会降低(尽管我需要找到特定的线程)。
归档时间: |
|
查看次数: |
2945 次 |
最近记录: |