当前位置 : 主页 > 网络安全 > 测试自动化 >

性能 – 为什么存储在单元格中的数据的访问时间短于矩阵?

来源:互联网 收集:自由互联 发布时间:2021-06-22
我在matlab中处理非常大的数据,并用于将这些数据存储在矩阵中.我曾经按行存储我的数据,但由于Matlab按列存储数据,我理解重塑我的矩阵所以我按列索引会使处理更快.这是我的意思的一
我在matlab中处理非常大的数据,并用于将这些数据存储在矩阵中.我曾经按行存储我的数据,但由于Matlab按列存储数据,我理解重塑我的矩阵所以我按列索引会使处理更快.这是我的意思的一个例子:

一般参数

nbr_channels = 20;
nbr_samples_per_channel = 3200000;
fake_data = randn(1, nbr_samples_per_channel);
ROI = 1200000 : 2800000;

按行分配数据

data = nan(nbr_channels, nbr_samples_per_channel);
tic; 
for j = 1 : nbr_channels
    data(j, 1:nbr_samples_per_channel) = fake_data; 
end; 
toc;

% Elapsed time is 1.476525 seconds.

从行矩阵返回数据

tic; 
for j = 1 : nbr_channels
    bla = data(j, ROI); 
end; 
toc;

% Elapsed time is 0.572162 seconds.

从行矩阵返回所有数据

tic; 
for j = 1 : nbr_channels
    bla = data(j, :); 
end; 
toc;

% Elapsed time is 0.589489 seconds.

按列分配数据

data = nan(nbr_samples_per_channel, nbr_channels);
tic; 
for j = 1 : nbr_channels
    data(1:nbr_samples_per_channel, j) = fake_data; 
end; 
toc;

% Elapsed time is 0.299682 seconds.

从列矩阵返回数据

tic; 
for j = 1 : nbr_channels
    bla = data(ROI, j); 
end; 
toc;

% Elapsed time is 0.260824 seconds.

从列矩阵返回所有数据

tic; 
f    or j = 1 : nbr_channels
    bla = data(:, j); 
end; 
toc;

% Elapsed time is 0.092983 seconds.

摘要第1部分:

我们可以看到,按列访问数据可将处理时间减少至少两倍!

但我不明白为什么细胞效率更高!看看这个例子:

按单元分配数据

data = cell(1, nbr_samples_per_channel);
tic; 
for j = 1 : nbr_channels
    data{j} = fake_data; 
end; 
toc;

% Elapsed time is 0.000013 seconds.

从单元格数组返回数据

tic; 
for j = 1 : nbr_channels
    bla = data{j}(ROI); 
end; 
toc;

% Elapsed time is 0.260294 seconds.

返回单元格数组中的所有数据

tic; 
for j = 1 : nbr_channels
    bla = data{j}; 
end; 
toc;

% Elapsed time is 0.000022 seconds.

%%

摘要第2部分:

这比我在第1部分中显示的要快几个数量级.

问题1

为什么存储在单元格中的数据的访问时间短于矩阵?

问题2

使用矩阵通常比使用单元格更容易,因为使用矩阵可以做到

my_matrix(100:20000,1:3)

但是对于细胞我不能这样做(据我所知).关于如何同时从多个单元格返回特定元素的任何替代方法?

你看到的是不同的时代,因为你没有做同等的事情.要比较两个案例:

按单元分配数据

>您正在创建一个单元格数组行向量,并在每个单元格的长双向量中填充
>每次循环迭代导致1将向量分配到单元阵列中的单个槽中
>正在完成’nbr_samples_per_channel’次数的分配.

按列分配数据

>您将浏览矩阵的列,并为每列中的每个元素指定一个向量
>每次循环迭代,无论使用简写冒号:您使用的符号,都可以解析为多个赋值. data(1:nbr_samples_per_channel,j)表示’nbr_samples_per_channel’赋值PER迭代.
>总的来说,你正在做’nbr_samples_per_channel’*’nbr_channels’的总分配.

为了说明我的观点,只需重新编写循环而不使用冒号操作符来显示所有分配.

for j = 1 : nbr_channels    

    n = length(fake_data)

    data(1,     j) = fake_data(1); 
    data(2,     j) = fake_data(1); 

    ... etc ...

    data(n - 1, j) = fake_data(n-1); 
    data(n,     j) = fake_data(n); 

end

所以,总而言之,你正在比较两个不同的东西,所以你不能说一个比另一个更快,因为它们不是等价的.

如果你只是循环一个双数组和一个单元格数组,并做常规分配….

%% Setup samples and pre-allocate
numberOfSamples = 100000;

doubleData = nan(numberOfSamples, 1);
cellData = cell(numberOfSamples, 1);

randomValues = rand(numberOfSamples, 1);

%% Assign N number of values to a double array
tic; 
for idx = 1 : numberOfSamples
    data(numberOfSamples) = randomValues(idx);
end
doubleTime = toc;

%% Assign N number of values to a cell array
tic; 
for idx = 1 : numberOfSamples
    cellData{numberOfSamples} = randomValues(idx);
end
cellTime = toc;

disp(sprintf('Double Array: %f seconds', doubleTime));
disp(sprintf('Cell   Array: %f seconds', cellTime));

你最终得到:

Double Array: 0.006073 seconds
Cell   Array: 0.032966 seconds

对于你的第二个问题,这是你想要做的吗?

>> bigCell = {1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16}

bigCell = 

    [ 1]    [ 2]    [ 3]    [ 4]
    [ 5]    [ 6]    [ 7]    [ 8]
    [ 9]    [10]    [11]    [12]
    [13]    [14]    [15]    [16]

>> subCell = bigCell(1:2, 3:4)

subCell = 

    [3]    [4]
    [7]    [8]

请注意,子单元仍然是一个单元格.通过使用()和而不是{}来访问单元格,您将其保留为单元格.

网友评论