2011-10-06 18 views
6

ho enormi prestazioni problemi con solo una piccolissima parte del mio MATLAB codice una speranza si potrebbe avere un idea di come migliorarlo:Rallentamento delle prestazioni quando si ripone gli oggetti manico in un array di celle

Sono lo sviluppo di una simulazione ad agenti in MATLAB che crea un sacco di oggetti maniglia. Alcuni di loro sono agenti che altri possono essere ad es. oggetti che sono di proprietà degli agenti.

di identificare chiaramente ognuno di questi oggetti maniglia ognuno ottiene un ID univoco (obj.Id) che viene rilasciato da un "IdDistributor" oggetto. Il IdDistributor stesso viene consegnato al costruttore di ciascun oggetto che deve resive un Id e viene chiamato da lì a dare un numero ID (giveId).

Inoltre il IdDistributor mantiene una sorta di telefonico (un IdRegistry) che associa ogni ID con l'oggetto. Quindi, dato l'Es si può cercare l'oggetto nel IdRegistry.

L'ho implementato utilizzando un array di celle che memorizza i diversi oggetti di handle esattamente in quel campo che corrisponde al loro Id. (La matrice normale non funziona poiché gli oggetti sono di classi diverse).

Test mia simulazione è veramente lento e il MATLAB Profiler mostra che il 99% del tempo è trascorso con la IdDistributor soprattutto con la linea che memorizza gli oggetti nella IdRegistry (Ci sono voluti qualcosa come 1 secondi per oggetto quando ho provato a creare circa 10.000 oggetti).

Ora sto provando a venire a una soluzione simile che richiede meno tempo. Come si può vedere nel seguente codice che ho già provato ad aumentare la velocità con pre-assegnazione (estendo le di 10.000 cellule IdRegistry quando è piena, invece di dimensionamento 1 da 1) .I anche pensato di cercare in qualche modo ottenere l'ID interno MATLAB degli oggetti handle ma non ha seguito quella strada quando ho letto che quell'Id non è permanente e può essere modificato dal sistema.

Apprezzerei molto qualsiasi idea su come velocizzare il codice o per trovare un rimedio/miglioramento al mio concetto!

Qui il mio codice:

La linea più lenta è IdDist.IdRegistry (IDNumber) = {obj};

btw. cambiandolo a IdDist.IdRegistry {IdNumber} = obj; non ha aiutato molto

classdef IdDistributor < handle 

properties 
    Id=int64(1); %Her own ID 
    LastId=int64(1); 
    IdRegistry={} 
end 

methods 
    function IdDist=IdDistributor() 
     IdDist.Id=int64(1); 
     IdDist.LastId=int64(1); 
     IdDist.register(IdDist); 
    end 
    function IdNum=giveId(IdDist,obj) 
     IdNum=IdDist.LastId+int64(1); 
     IdDist.LastId=IdNum; 
     IdDist.register(obj,IdNum) 
    end 
    function register(IdDist,obj,IdNum) 
     if nargin==2  
      IdNumber=obj.Id; 
     elseif nargin==3 
      IdNumber=IdNum; 
     end 
      if IdNumber>=length(IdDist.IdRegistry) %Extend the Register by 10000 
       IdDist.IdRegistry(IdNumber+10000)={[]};  
      end 
      if IdNumber >0 
       IdDist.IdRegistry(IdNumber)={obj}; 
      end 
    end %function 
    end %methods 
    end %class 
+0

Ho provato a modificare la pre-allocazione in: _IdDist.IdRegistry (IdNumber + 10000) = {SomeDummyHandleObject}; _ perché un amico ha suggerito che la dimensione della cella potrebbe cambiare da una cella vuota {[]} a quando viene memorizzato un riferimento all'oggetto handle e potrebbe causare la riallocazione della memoria da parte di Matlab. Tuttavia, questo è stato salvato solo 0,009 secondi su 1,428 secondi in _IdDistributor.register_. – Jacob

+0

Qual è il consumo di memoria come quando si esegue 'lento'? È possibile che si stiano facendo delle copie degli oggetti invece di memorizzare solo le maniglie? – zeFrenchy

+1

Dato che sono tutti oggetti di gestione Matlab, sarei sorpreso se fossero/potrebbero essere copiati. Ho comunque apportato un notevole miglioramento modificando il tipo di IdRegistry da _Cell_ a _Map_. Stavo per pubblicare la mia soluzione, ma lo stackoverflow mi obbliga ad aspettare 8 ore da quando sono nuovo. Ecco in breve: Modifica nella sezione delle proprietà: IdRegistry = containers.Map ('KeyType', 'int64', 'ValueType', 'any'); Eliminato il blocco di pre-assegnazione; modifica della registrazione in: IdDist.IdRegistry (IdNumber) = obj; ; PRENDE ORA SOLO il 17% delle volte. Non so perché. Risposta completa in poche ore. – Jacob

risposta

2

Dal momento che non sei l'eliminazione di oggetti dal registro, come si potrebbe provare derivante tutti gli oggetti dalla classe matlab.mixin.Heterogeneous, quindi memorizzandoli in una serie regolare.Si noti che questo richiederà R2011a o più recente.

Non so se questo è più veloce, ma è qualcosa da provare. Ovviamente sarà utile solo se tutti gli ID sono generati da IdDistributor, poiché sono sequenziali.

Inoltre, i miei test suggeriscono che

length(IdDist.IdRegistry) 

è anche lento, quindi è possibile memorizzare la lunghezza del Registro di sistema nella IdDistributor pure. e suggerirei di impostare SetAccess su protected per le proprietà, per sicurezza.

+0

True length (IdDist.IdRegistry) richiede un po 'di tempo. Cercherò minin.Heterogenous quando ho aggiornato la mia versione del programma. – Jacob

0

Ho esaminato ulteriormente il problema e mi sembra che in realtà la maggior parte del tempo si perde nel processo di chiamare il metodo giveId di IdDistributer da un oggetto diverso e non tanto all'interno del metodo.

Ho anche identificato altri punti del mio programma in cui si verificano problemi simili. Soprattutto quando molti oggetti di handle sono costruiti e memorizzati in una matrice e questa matrice viene archiviata come proprietà di un oggetto. Pertanto, la causa originale della prestazione lenta potrebbe risiedere in questo poiché IdDistributer viene solitamente utilizzato quando vengono creati nuovi oggetti handle.

Poiché questo è un argomento un po 'diverso ho pubblicato un altro question tra cui un semplice codice per l'illustrazione.

+0

Ci sono in realtà alcune risposte correlate a questa domanda sotto la mia [nuova domanda] (http://stackoverflow.com/questions/7726487/how-to-avoid-matlab-taking-exponential-time-when-creating-a-handle -object-array-a/7727501 # 7727501) delineato sopra. Potrebbero essere utili se molti oggetti della stessa classe devono essere memorizzati contemporaneamente nella proprietà di un altro oggetto. – Jacob

Problemi correlati