Когда уместно использовать массив ячеек вместо структуры в Matlab? - PullRequest
17 голосов
/ 03 сентября 2010

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

structArray(structIndex).structField

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

cellArray{cellIndex}

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

Ответы [ 4 ]

15 голосов
/ 03 сентября 2010

На мой взгляд, это больше вопрос удобства и ясности кода. Спросите себя, предпочитаете ли вы ссылаться на ваши переменные элементы по номерам или по имени. Затем используйте массив ячеек в первом случае и массив структур позже. Думайте об этом, как будто у вас есть таблица с заголовками и без них.

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

9 голосов
/ 03 сентября 2010

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

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

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

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

6 голосов
/ 06 декабря 2010

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

Запуск «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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 голосов
/ 03 сентября 2010

Во-первых, я второй ответ Юка.Ясность, как правило, важнее в долгосрочной перспективе.

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

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

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

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

...