3

我目前正在处理一个涉及保存/加载相当大的 MAT 文件(大约 150 MB)的项目,我意识到访问加载的单元数组比在脚本或函数中创建的等效版本要慢得多。

我创建了这个示例来模拟我的代码并显示差异:

clear; clc;

disp('Test for computing with loading');

if exist('data.mat', 'file')
    delete('data.mat');
end

n_tests = 10000;
data = {};
for i=1:n_tests
    data{end+1} = rand(1, 4096);
end

% disp('Saving data');
% save('data.mat', 'data');
% clear('data');
% 
% disp('Loading data');
% load('data.mat', '-mat');

for i=1:n_tests
    tic;
    for j=1:n_tests
        d = sum((data{i} - data{j}) .^ 2);
    end
    time = toc;
    disp(['#' num2str(i) ' computed in ' num2str(time) ' s']);
end

在此代码中,没有保存或加载任何 MAT 文件。在 i 上一次迭代的平均时间是 0.75 秒。当我取消注释保存/加载文件的行时,对 i 进行一次迭代的计算大约需要 6.2 秒(不考虑保存/加载时间)。差别慢了 8 倍!

我正在使用 MATLAB 7.12.0 (R2011a) 64 位和 Windows 7 64 位,并且 MAT 文件以 v7.3 版本保存。

会不会和MAT文件的压缩有关?还是缓存变量?有什么方法可以防止/避免这种情况吗?

4

2 回答 2

5

我也知道这个问题。我认为这也与 matlab 中内存管理效率低下有关——而且我记得它在交换方面做得不好。一个 150MB 的文件可以轻松容纳大量数据 - 可能超过快速分配的数据。

我刚刚使用mathworks 提供的信息对您的示例进行了快速计算, 在您的情况下total_size = n_tests*121 + n_tests*(1*4096* 8)大约为 313MB。

首先,我建议将它们保存为格式 7(而不是 7.3)——我注意到读取这种新格式的性能非常差。仅此一项就可能是您减速的原因。

我个人通过两种方式解决了这个问题:

  1. 将数据拆分为较小的集合,然后使用在需要时加载数据或动态创建数据的函数(可以通过类优雅地完成)
  2. 将数据移动到数据库中。SQLite 和 MySQL 都很棒。两者都可以有效地处理更大的数据集(在 TB 中而不是 GB 中)。SQL 语言在快速获取要操作的子集方面非常有效。
于 2011-11-28T12:14:04.303 回答
-1

我使用 Windows 64bit、matlab 64bit 2014b 测试此代码。

不保存和加载,计算在0.22s左右,用'-v7'保存数据文件再加载,计算在0.2s左右。用'-v7.3'保存数据文件然后加载,计算时间约为4.1s。所以和MAT文件的压缩有关。

于 2015-05-10T06:55:59.903 回答