MATLAB: доступ к загруженному файлу MAT очень медленный - PullRequest
3 голосов
/ 28 ноября 2011

В настоящее время я работаю над проектом, предусматривающим сохранение / загрузку довольно больших файлов MAT (около 150 МБ), и я понял, что доступ к загруженному массиву ячеек был намного медленнее, чем эквивалентная версия, созданная в скрипте или функции.

Я создал этот пример, чтобы смоделировать мой код и показать разницу:

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?Или кеширование переменных?Есть ли способ предотвратить / избежать этого?

Ответы [ 2 ]

5 голосов
/ 28 ноября 2011

Я тоже знаю эту проблему. Я думаю, что это также связано с неэффективным управлением памятью в Matlab - и, насколько я помню, с обменом не все в порядке. Файл объемом 150 МБ может легко содержать много данных - возможно, больше, чем может быть быстро выделено.

Я только что сделал быстрый расчет для вашего примера, используя информацию от mathworks В вашем случае total_size = n_tests*121 + n_tests*(1*4096* 8) составляет около 313 МБ.

Сначала я бы предложил сохранить их в формате 7 (вместо 7.3) - я заметил очень низкую производительность при чтении этого нового формата. Это само по себе может быть причиной вашего замедления.

Лично я решил это двумя способами:

  1. Разделите данные на более мелкие наборы, а затем используйте функции, которые загружают данные при необходимости или создают их на лету (это можно элегантно сделать с помощью классов)
  2. Переместить данные в базу данных. SQLite и MySQL великолепны. Оба эффективно работают с НАМНОГО большими наборами данных (в ТБ, а не в ГБ). А язык SQL достаточно эффективен для быстрого получения подмножеств для манипулирования.
0 голосов
/ 10 мая 2015

Я тестирую этот код с 64-битной Windows, 64-битной Matlab 2014b.

Без сохранения и загрузки вычисление занимает около 0,22 с, Сохраните файл данных с помощью '-v7' и затем загрузите, вычисление составляет около 0,2 с. Сохраните файл данных с помощью '-v7.3' и затем загрузите, вычисление составляет около 4,1 с. Так что это связано со сжатием файла MAT.

...