2010-09-03 34 views
17

Nếu tôi muốn lưu trữ một số chuỗi hoặc ma trận của các kích cỡ khác nhau trong một biến duy nhất, tôi có thể nghĩ đến hai lựa chọn: Tôi có thể làm cho một cấu trúc mảng và có một trong các lĩnh vực tổ chức các dữ liệu,Khi nào thích hợp để sử dụng mảng ô so với cấu trúc trong Matlab?

structArray(structIndex).structField 

hoặc Tôi có thể sử dụng mảng ô,

cellArray{cellIndex} 

nhưng có nguyên tắc chung khi sử dụng cấu trúc dữ liệu nào không? Tôi muốn biết nếu có những nhược điểm để sử dụng một hoặc khác trong những tình huống nhất định.

Trả lời

15

Theo ý kiến ​​của tôi, vấn đề thuận tiện và mã rõ ràng hơn. Hãy tự hỏi mình có muốn giới thiệu các yếu tố biến của bạn theo số hay tên. Sau đó sử dụng mảng ô trong trường hợp trước đây và mảng cấu trúc sau này. Hãy suy nghĩ về nó như thể bạn có một cái bàn có và không có tiêu đề.

Bằng cách này, bạn có thể dễ dàng chuyển đổi giữa các cấu trúc và ô bằng các hàm CELL2STRUCTSTRUCT2CELL.

+4

Với mảng ô, bạn cần một số dữ liệu meta để xác định nội dung ô. Các tên trường được chọn cẩn thận làm cho mã của bạn tự giải thích. – zellus

9

Nếu bạn sử dụng nó để tính toán trong một hàm, tôi khuyên bạn nên sử dụng mảng ô, vì chúng thuận tiện hơn để xử lý, cảm ơn ví dụ: đến CELLFUN. Tuy nhiên, nếu bạn sử dụng nó để lưu trữ dữ liệu (và trả về đầu ra), tốt hơn là trả về cấu trúc, vì tên trường là (nên) tự ghi lại tài liệu, vì vậy bạn không cần nhớ thông tin nào bạn đã có trong cột 7 của mảng ô của bạn. Ngoài ra, bạn có thể dễ dàng bao gồm một trường 'trợ giúp' trong cấu trúc của bạn, nơi bạn có thể đặt thêm một số giải thích về các trường, nếu cần.

Cấu trúc cũng hữu ích cho việc lưu trữ dữ liệu vì bạn có thể cập nhật mã của bạn sau này, thay thế chúng bằng các đối tượng mà không cần thay đổi mã của bạn (ít nhất là trong trường hợp bạn đã gán trước cấu trúc của mình)). Chúng có cùng sytax, nhưng các đối tượng sẽ cho phép bạn thêm nhiều chức năng hơn, chẳng hạn như các thuộc tính phụ thuộc (tức là các thuộc tính được tính toán trên bay dựa trên các thuộc tính khác).

Cuối cùng, lưu ý rằng các ô và cấu trúc thêm một vài byte trên không cho mọi trường. Do đó, nếu bạn muốn sử dụng chúng để xử lý một lượng lớn dữ liệu, bạn nên sử dụng các cấu trúc/ô chứa mảng hơn là có mảng lớn các cấu trúc/ô nơi các trường/phần tử chỉ chứa vô hướng.

2

Đầu tiên và trước hết, tôi trả lời câu trả lời thứ hai của yuk. Rõ ràng nói chung là quan trọng hơn trong thời gian dài.

Tuy nhiên, bạn có thể có hai lựa chọn hơn tùy thuộc vào cách đột xuất hình dữ liệu của bạn là:

Lựa chọn 3: structScalar.structField(fieldIndex)

Lựa chọn 4: structScalar.structField{cellIndex}

Trong số bốn, # 3 có ít nhất chi phí bộ nhớ cho số lượng lớn các phần tử (nó giảm thiểu tổng số ma trận), và theo số lượng lớn tôi có nghĩa là> 100.000. Nếu mã của bạn vay chính nó để vector hóa trên structField, nó có thể là một chiến thắng hiệu suất, quá. Nếu bạn không thể thu thập từng phần tử của structField vào một ma trận đơn, tùy chọn 4 có lợi ích không hợp lý mà không có bộ nhớ & lợi thế hiệu suất của tùy chọn 3. Cả hai tùy chọn này đều giúp dễ dàng sử dụng arrayfun hoặc cellfun trên toàn bộ tập dữ liệu, tại chi phí yêu cầu bạn thêm hoặc xóa các phần tử khỏi từng trường riêng lẻ.Sự lựa chọn phụ thuộc vào cách bạn sử dụng dữ liệu của bạn, điều này đưa chúng ta trở lại câu trả lời của yuk - chọn điều làm cho mã rõ ràng nhất.

6

Mã này cho thấy rằng các mảng ô có thể nhanh gấp hai lần các cấu trúc để gán và truy xuất. Tôi đã không tách hai hoạt động. Người ta có thể dễ dàng sửa đổi mã để làm điều đó.

Chạy "whos" sau đó cho thấy rằng chúng sử dụng lượng bộ nhớ rất giống nhau.

Mục tiêu của tôi là tạo danh sách "danh sách" trong thuật ngữ python. Có lẽ một "mảng mảng".

Tôi hy vọng điều này thật thú vị/hữu ích!

%%%%%%%%%%%%%% 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

Ồ, và cảm ơn @jonas đã kể cho tôi nghe về CELLFUN. Tôi không biết về chức năng đó và sẽ sử dụng nó trong mã tôi đang làm việc ngay bây giờ. – abalter

+0

theo mã của bạn 'struct' nhanh gấp bốn lần trong trường hợp của tôi – embert

Các vấn đề liên quan