Когда целесообразно использовать массив ячеек против структуры в Matlab?

17

Если я хочу хранить некоторые строки или матрицы разных размеров в одной переменной, я могу представить два варианта: я мог бы создать массив структур и иметь одно из полей, содержащих данные,

structArray(structIndex).structField

, или я мог бы использовать массив ячеек,

cellArray{cellIndex}

, но существует ли общее правило, когда использовать эту структуру данных? Я хотел бы знать, есть ли недостатки для использования того или другого в определенных ситуациях.

    
задан CJS 03.09.2010 в 15:00
источник

4 ответа

15

По-моему, это скорее вопрос удобства и четкости кода. Спросите себя, предпочитаете ли вы ссылаться на свои переменные элементы по номерам или по имени. Затем используйте массив ячеек в предыдущем массиве case и struct. Подумайте об этом, как будто у вас есть стол с заголовками и без них.

Кстати, вы можете легко преобразовать структуры и ячейки с помощью CELL2STRUCT и STRUCT2CELL .

    
ответ дан yuk 03.09.2010 в 15:28
  • С помощью массивов ячеек вам нужны некоторые метаданные, чтобы идентифицировать содержимое ячейки. Тщательно выбранные имена полей делают ваш код сам объяснением. –  zellus 03.09.2010 в 18:55
9

Если вы используете его для вычисления внутри функции, я предлагаю вам использовать массивы ячеек, поскольку они удобнее обрабатывать, например, например. на CELLFUN .

Однако, если вы используете его для хранения данных (и возвращаемого вывода), лучше возвращать структуры, так как имена полей (должны быть) самодокументированы, поэтому вам не нужно помнить, какая информация у вас была в столбец 7 вашего массива ячеек. Кроме того, вы можете легко включить полевую «справку» в свою структуру, где при необходимости вы можете добавить дополнительное объяснение полей.

Структуры также полезны для хранения данных, поскольку вы можете, если хотите обновить свой код позднее, замените их на объекты, не изменяя свой код (по крайней мере, если вы предварительно назначили свою структуру) , Они имеют один и тот же ситакс, но объекты позволят вам добавить больше функциональных возможностей, таких как зависимые свойства (т. Е. Свойства, которые вычисляются «на лету» на основе других свойств).

Наконец, обратите внимание, что ячейки и структуры добавляют несколько байтов служебных данных для каждого поля. Таким образом, если вы хотите использовать их для обработки больших объемов данных, вам гораздо лучше использовать структуры / ячейки, содержащие массивы, а не иметь большие массивы структур / ячеек, где поля / элементы содержат только скаляры.     

ответ дан Jonas 03.09.2010 в 20:45
6

Этот код предполагает, что массивы ячеек могут быть примерно в два раза быстрее, чем структуры для назначения и поиска. Я не разделял две операции. Для этого можно легко изменить код.

Запуск «whos» впоследствии предполагает, что они используют очень похожие объемы памяти.

Моя цель состояла в том, чтобы создать «список списков» в терминологии python. Возможно, это «массив массивов».

Надеюсь, это интересно / полезно!

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
ответ дан abalter 06.12.2010 в 01:13
  • О, и спасибо @jonas за рассказ о CELLFUN. Я не знал об этой функции и буду использовать ее в коде, над которым я сейчас работаю. –  abalter 06.12.2010 в 01:16
  • в соответствии с вашей структурой кода в четыре раза быстрее в моем случае –  embert 21.08.2014 в 16:48
2

Прежде всего, я отвечу на второй юк. Ясность обычно более важна в долгосрочной перспективе.

Однако у вас может быть еще два варианта в зависимости от того, как ваши данные имеют неправильную форму:

Вариант 3: structScalar.structField(fieldIndex)

Вариант 4: structScalar.structField{cellIndex}

Среди четырех, # 3 имеет наименьшие издержки памяти для большого количества элементов (это сводит к минимуму общее число матриц), а большими числами - & gt; 100 000. Если ваш код поддается векторизации на structField , это, вероятно, также и победа в производительности. Если вы не можете собрать каждый элемент structField в одну матрицу, опция 4 имеет нотные преимущества без памяти & amp; преимуществами варианта 3. Оба этих варианта упрощают использование arrayfun или cellfun во всем наборе данных за счет необходимости добавлять или удалять элементы из каждого поля отдельно. Выбор зависит от того, как вы используете свои данные, что возвращает нас к ответу yuk - выберите, что делает для самого чистого кода.

    
ответ дан Arthur Ward 03.09.2010 в 21:26