2010-09-03 14 views
17

Si quiero almacenar algunas cadenas o matrices de diferentes tamaños en una sola variable, puedo pensar en dos opciones: podía hacer una serie estructura y tienen uno de los campos contienen los datos,¿Cuándo es apropiado usar una matriz de celdas frente a una estructura en Matlab?

structArray(structIndex).structField 

o podría utilizar una serie de células,

cellArray{cellIndex} 

pero ¿hay una regla empírica de cuándo utilizar el que la estructura de datos general? Me gustaría saber si hay desventajas de usar uno u otro en ciertas situaciones.

Respuesta

15

En mi opinión, es más una cuestión de conveniencia y claridad de código. Pregúntese si prefiere referir sus elementos variables por número (s) o por nombre. A continuación, utilice la matriz de celdas en el caso anterior y la matriz de estructuras en adelante. Piense en ello como si tuviera una mesa con y sin encabezados.

Por cierto, puede convertir fácilmente estructuras y celdas con las funciones CELL2STRUCT y STRUCT2CELL.

+4

Con matrices de celdas necesita algunos metadatos para identificar el contenido de la celda. Los nombres de campo cuidadosamente seleccionados hacen que su código sea autoexplicativo. – zellus

9

Si lo usa para el cálculo dentro de una función, le sugiero que use matrices de celdas, ya que son más fáciles de manejar, gracias p. Ej. a CELLFUN.

Sin embargo, si lo usa para almacenar datos (y devolver resultados), es mejor devolver las estructuras, ya que los nombres de campo son (deberían) autodocumentados, por lo que no necesita recordar qué información tenía en la columna 7 de tu matriz de células. Además, puede incluir fácilmente un campo de "ayuda" en su estructura, donde puede agregar alguna explicación adicional de los campos, si es necesario.

Las estructuras también son útiles para el almacenamiento de datos ya que puede, si desea actualizar su código en una fecha posterior, reemplazarlos con objetos sin necesidad de cambiar su código (al menos en caso de que haya realizado una asignación previa de su estructura) Tienen el mismo sintaxis, pero los objetos le permitirán agregar más funcionalidades, como propiedades dependientes (es decir, propiedades que se calculan sobre la marcha en función de otras propiedades).

Finalmente, tenga en cuenta que las celdas y las estructuras agregan unos pocos bytes de sobrecarga a cada campo. Por lo tanto, si desea usarlos para manejar grandes cantidades de datos, es mucho mejor que use estructuras/celdas que contienen matrices, en lugar de tener grandes matrices de estructuras/celdas donde los campos/elementos solo contienen escalares.

2

En primer lugar, respondí la segunda respuesta de yuk. La claridad es generalmente más importante a largo plazo.

Sin embargo, es posible que tenga dos opciones más dependiendo de la forma irregular de sus datos es:

Opción 3: structScalar.structField(fieldIndex)

Opción 4: structScalar.structField{cellIndex}

Entre los cuatro, # 3 tiene la menor la sobrecarga de memoria para grandes cantidades de elementos (minimiza el número total de matrices), y para grandes números quiero decir> 100.000. Si su código se presta para vectorizar en structField, es probable que también gane rendimiento. Si no puede recopilar cada elemento de structField en una matriz única, la opción 4 tiene los beneficios de notación sin la memoria & ventajas de rendimiento de la opción 3. Ambas opciones facilitan el uso de arrayfun o cellfun en todo el conjunto de datos, en el costo de requerir que agregue o elimine elementos de cada campo individualmente.La elección depende de cómo uses tus datos, lo que nos lleva de vuelta a la respuesta de yuk: elige qué hace que el código sea más claro.

6

Este código sugiere que las matrices de celdas pueden ser aproximadamente el doble de rápidas que las de asignación y recuperación. No separé las dos operaciones. Uno podría modificar fácilmente el código para hacer eso.

Correr "whos" luego sugiere que usan cantidades de memoria muy similares.

Mi objetivo era hacer una "lista de listas" en la terminología de Python. Quizás una "matriz de matrices".

¡Espero que esto sea interesante/útil!

%%%%%%%%%%%%%% StructVsCell.m %%%%%%%%%%%%%%% 

clear all 

M = 100; % number of repetitions 
N = 2^10; % size of cell array and struct 


for m = 1:M 
    % Fill up a template cell array with 
    % lists of randomly sized matrices with 
    % random elements. 
    template{N} = 0; 
    for n = 1:N 
     r1 = round(24*rand()); 
     r2 = round(24*rand()); 
     r3 = rand(round(r2*rand),round(r1*rand())); 
     template{N} = r3; 
    end 

    % Make a cell array equivalent 
    % to the template. 
    cell_array = template; 

    % Create a struct with the 
    % same data. 
    structure = struct('data',0); 
    for n = 1:N 
     structure(n).data = template{n}; 
    end 

    % Time cell array 
    tic; 
    for n = 1:N 
     data = cell_array{n}; 
     cell_array{n} = data'; 
    end 
    cell_time(m) = toc; 

    % Time struct 
    tic; 
    for n = 1:N 
     data = structure(n).data; 
     structure(n).data = data'; 
    end 
    struct_time(m) = toc; 
end 

str = sprintf('cell array: %0.4f',mean(cell_time)); 
disp(str); 
str = sprintf('struct: %0.4f',mean(struct_time)); 
disp(str); 
str = sprintf('struct_time/cell_time: %0.4f',mean(struct_time)/mean(cell_time)); 
disp(str); 

% Check memory use 
whos 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
+0

Ah, y gracias @jonas por contarme sobre CELLFUN. No sabía acerca de esa función y la usaré en el código en el que estoy trabajando en este momento. – abalter

+0

según su código 'struct' es cuatro veces más rápido en mi caso – embert

Cuestiones relacionadas