how preallocate structure for better memory

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?

 Akzeptierte Antwort

Jan
Jan am 22 Sep. 2012
Bearbeitet: Jan am 2 Okt. 2017

27 Stimmen

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.

5 Kommentare

Jason
Jason am 13 Dez. 2012
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 am 13 Dez. 2012
Bearbeitet: Jan am 13 Dez. 2012
@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.
alternatively syntax worked . Thanks
thanks! that
head = struct('number', cell(1, 10), 'pck_rv', cell(1, 10));
work fine!
Dyuman Joshi
Dyuman Joshi am 27 Mär. 2024
I am accepting Jan's answer as it provides a robust solution to the question posted.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (2)

Azzi Abdelmalek
Azzi Abdelmalek am 22 Sep. 2012
Bearbeitet: Azzi Abdelmalek am 22 Sep. 2012

5 Stimmen

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 Kommentare

This should be the top answer IMO :)
Jan
Jan am 2 Okt. 2017
@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.
True, I just tried it out and realised it wasn't what I wanted either! Thanks for the response.

Melden Sie sich an, um zu kommentieren.

Walter Roberson
Walter Roberson am 13 Dez. 2012

2 Stimmen

head = struct('number', {3, 5}, 'pck_rcv', {[1 0 0], [1 0 1]})

Kategorien

Mehr zu Variables finden Sie in Hilfe-Center und File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by