MATLAB Answers

how preallocate structure for better memory

627 ビュー (過去 30 日間)
Salvatore Mazzarino
Salvatore Mazzarino 2012 年 9 月 22 日
コメント済み: Alexandra Simpson 2017 年 10 月 2 日
I had created a structure made so:
head.number = 3;
head.pck_rcv = [1 0 0];
heads(2).number = 5;
head(2).pck_rcv = [1 1 0];
and so on.
How can I preallocate a structure?

  0 件のコメント

サインインしてコメントする。

回答 (3 件)

Jan
Jan 2012 年 9 月 22 日
編集済み: Jan 2017 年 10 月 2 日
for k = n:-1:1 % Backwards!
head(k).number = 3;
head(k).pck_rcv = [1 0 0];
end
Now the final size of the struct array is created in the first iteration.
[EDITED] Alternatively:
head = struct('number', cell(1, 10), 'pck_rv', cell(1, 10));
Now head is a [1 x 10] struct array withe the fields 'number' and 'pck_rv'. Pre-allocating the contents of the fields is another job and you need a loop to do this. But now it can run in forward direction also.

  2 件のコメント

Jason
Jason 2012 年 12 月 13 日
Jan, can you clarify something for me? On an earlier question, http://www.mathworks.com/matlabcentral/answers/30764#answer_39237 you gave the same suggestion. Oleg showed a test case where preallocating a struct by initializing the last element didn't appear to result in sufficient memory being allocated. Which is correct?
Jan
Jan 2012 年 12 月 13 日
@Jason: I've added a comment to Oleg's message now. There are two jobs to to when pre-allocating a struct array: 1. allocate the struct array itself, 2. allocate memory for all different fields. While point 1 can be solved in one step using either the struct('field', {data}) or the implicit pre-allocation by assigning the last element at first, the allocation of the contents of the fields cannot be done in one step. There is no way to pre-allocate n arrays simultaneously. Trying to do this results in "shared data copies", which means that all the fields share the same data value. At first this is fast and memory efficient. But when you change the values, an addition deep copy is performed for each element, which consumes more time than allocating the different arrays of the fields in a loop. For this reasons it is e.g. useless to "pre-allocate" the elements of a cell array, while pre-allocating the cell itself is strongly recommended:
n = 1e5;
tic; for k = 1:1000
clear('c');
for in = 1:n
c{in} = 'qvw';
end
end, toc
tic; for k = 1:1000
clear('c');
c = cell(1, n); % important pre-allocation of cell
c(:) = {'asd'}; % Useless pre-allocation of cell elements
% Now all elements of C point to the same memory such that
% the characters 'asd' are found once only in the RAM.
for in = 1:n
c{in} = 'qvw'; % Now "unsharing" the string consumes time
end
end, toc
tic; for k = 1:1000
clear('c');
c = cell(1, n); % important pre-allocation of cell
for in = 1:n
c{in} = 'qvw';
end
end, toc
This is very similar for structs, because the only difference to cells is the storage of the fieldnames in a CHAR array, while the organization of the elements is equal (therefore struct2cell and cell2struct are so fast).
Summary: Pre-allocate the struct in one step, pre-allocate the fields separately for each element of the struct in a loop, or assign them directly if possible.

サインインしてコメントする。


Azzi Abdelmalek
Azzi Abdelmalek 2012 年 9 月 22 日
編集済み: Azzi Abdelmalek 2012 年 9 月 22 日
heads=struct('numbers',zeros(10,1), 'pck_rcv',zeros(10,3))
%then
for k=1:n
heads.numbers(k)=2
heads.pck_rcv(k,:)=[1 2 3]
end

  3 件のコメント

Alexandra Simpson
Alexandra Simpson 2017 年 10 月 2 日
This should be the top answer IMO :)
Jan
Jan 2017 年 10 月 2 日
@Alexandra: I do not agree. Salvatore asked for a struct array: "head(2).numbers and so on". Azzi's suggestion creates a scalar struct only.
Alexandra Simpson
Alexandra Simpson 2017 年 10 月 2 日
True, I just tried it out and realised it wasn't what I wanted either! Thanks for the response.

サインインしてコメントする。


Walter Roberson
Walter Roberson 2012 年 12 月 13 日
head = struct('number', {3, 5}, 'pck_rcv', {[1 0 0], [1 0 1]})

  0 件のコメント

サインインしてコメントする。

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by