2011-11-28 7 views
3

Je travaille actuellement sur un projet impliquant l'enregistrement/chargement de gros fichiers MAT (environ 150 Mo), et je me suis rendu compte qu'il était beaucoup plus lent d'accéder à une matrice de cellules chargées que l'équivalent version créée à l'intérieur d'un script ou d'une fonction.MATLAB: accès fichier MAT chargé très lent

J'ai créé cet exemple pour simuler mon code et montrer la différence:

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 

Dans ce code, aucun fichier MAT est enregistré ni chargé. La durée moyenne d'une itération sur i est de 0,75s. Lorsque je décommente les lignes pour enregistrer/charger le fichier, le calcul pour une itération sur i prend environ 6,2 s (le temps d'enregistrement/chargement n'est pas pris en compte). La différence est 8 fois plus lente! J'utilise MATLAB 7.12.0 (R2011a) 64 bits avec Windows 7 64 bits, et les fichiers MAT sont enregistrés avec la version v7.3.

Peut-il être lié à la compression du fichier MAT? Ou des variables de mise en cache? Y at-il un moyen de prévenir/éviter cela?

+0

Y at-il une raison importante pour laquelle vous utilisez des cellules et non une matrice? – cyborg

+0

En fait, la différence avec ou sans matrices d'enregistrement/chargement est plus petite que pour les matrices de cellules, mais le problème est toujours là: pour 10000 tests, le calcul est 4.3s vs 1.5s pour matrices (10000 lignes) et 6.1s vs 0.4s pour les baies de cellules (10000 éléments) –

Répondre

5

Je connais aussi ce problème. Je pense que c'est aussi lié à la gestion inefficace de la mémoire dans matlab - et je me souviens que ça ne va pas bien avec l'échange. Un fichier de 150 Mo peut facilement contenir beaucoup de données - peut-être plus que ce qui peut être rapidement alloué.

Je viens de faire un calcul rapide pour votre exemple en utilisant le information by mathworks Dans votre cas total_size = n_tests*121 + n_tests*(1*4096* 8) est d'environ 313MB.

D'abord, je suggère de les enregistrer au format 7 (au lieu de 7,3) - J'ai remarqué une très mauvaise performance dans la lecture de ce nouveau format. Cela seul pourrait être la raison de votre ralentissement.

Personnellement, je résolus de deux manières:

  1. diviser les données en ensembles plus petits, puis utiliser les fonctions qui chargent les données en cas de besoin ou de créer à la volée (peut être fait avec élégance avec des classes)
  2. Déplacez les données dans une base de données. SQLite et MySQL sont géniaux. Les deux fonctionnent efficacement avec BEAUCOUP plus de jeux de données (dans les TB au lieu des GB). Et le langage SQL est assez efficace pour obtenir rapidement des sous-ensembles à manipuler.
+0

La taille est d'environ 300 Mo en effet ... mais il devrait être facilement gérable par MATLAB 64 bits, n'est-ce pas? J'ai changé le format de 7.3 à 7 et il n'y a plus de ralentissement, les performances sont les mêmes avec ou sans sauvegarde! Je jetterai un coup d'oeil à SQL pour l'avenir, car les données pourraient être beaucoup plus grandes que cela. Finalement, il y a toujours cette différence entre les matrices de cellules et les matrices (la première est plus rapide). Pourrait-il être lié à la taille de la matrice et à sa gestion de la mémoire? En tout cas, merci beaucoup pour le pourboire! –

+0

+1 D'accord, j'utilise personnellement MS SQL Server Express qui est distribué avec un bon outil de gestion gratuit - utile si vous êtes nouveau dans ce domaine. En ce qui concerne la connexion à dbs, je recommande d'utiliser cette bibliothèque http://www.mathworks.com/matlabcentral/fileexchange/29615-adodbtools au lieu de celle intégrée à Matlab. – James

-1

Je teste ce code avec Windows 64bit, matlab 64bit 2014b.

Sans sauvegarde et chargement, le calcul est d'environ 0,22s, Enregistrez le fichier de données avec '-v7', puis chargez, le calcul est d'environ 0,2 s. Enregistrez le fichier de données avec '-v7.3', puis chargez, le calcul est d'environ 4.1s. Il est donc lié à la compression du fichier MAT.

+0

essayez d'aborder les questions posées et le problème qui a été soulevé – Lupin