I would like to understand the difference between container map and a struct in matlab.
From what I've looked, it seems that the advantages of a container map is that it can use any number or string as a key, while a struct field can only take strings that are legit variable names (e.g. it won't accept mystruct.('123string')
)
Are there any other advantages for using a container map over a struct?
Thanks
Objects with keys that index to values, where keys need not be integers. Store data values in a Map object, which is a data structure that associates each value with a corresponding key. A Map object is similar to a dictionary or associative array in that you can use keys to retrieve values from it.
1. n. [Geology] A type of subsurface map whose contours represent the elevation of a particular formation, reservoir or geologic marker in space, such that folds, faults and other geologic structures are clearly displayed.
A map function basically takes the elements of the array and applies a function to each element. The resultant output is of the same shape as the array, but the values are the result of the function.
As @marsei remarked in his comment, container maps are a Java-based, unordered, construct, that uses hash-tables for indexing. A struct is a different construct, which is C-based and ordered (thanks for the insignt @marsei).
The keyword used for a structure in Matlab is “struct” Array of a structure is also possible in Matlab. A struct can have a single field, many fields, and even no field. It can be one dimensional or multi-dimensional. Value to the structure can be added using a structure name and filedname connected with the dot operator.
A container map is used to create a mapping or indexing. For example if you have a matrix A and want to index the element in the second row and second column, you will index it using A (2,2). For numbers, matrices and so on, where you want to index a specific row number, this is convenient.
Difference between Array and Map. An Array is a collection of elements of the same data type. The map is a hashed structure of key and value pairs. The indices of the list are integers starting from 0. The keys of the Map can be of any data type. The elements are accessed via indices.
The concepts behind a container map and a struct are quite different:
A container map is used to create a mapping or indexing. For example if you have a matrix A
and want to index the element in the second row and second column, you will index it using A(2,2)
. For numbers, matrices and so on, where you want to index a specific row number, this is convenient. Assume however, you have a situation as shown in the following example by Mathworks:
Here you have an array of values, which you could index as value(1)
for January, and so on. However this is not very legible. It would be much more convenient if you could index it with value('Jan')
. This is exactly what container maps offer. As @marsei remarked in his comment, container maps are a Java-based, unordered, construct, that uses hash-tables for indexing.
A struct is a different construct, which is C-based and ordered (thanks for the insignt @marsei). The main use of struct is to help you store data in a more logical way. For example when using images, you often have two variables: one for the image data, and one for the color map. Without structs, you need to keep those two separate variables in the workspace. For multiple images this gets very confusing (e.g. using names like img0_data
, img0_map
and so on). A struct helps you organize this in a simple way: A struct called img0
with the fields data
and map
.
In the context of dictionaries, both constructs are more or less equivalent, though structs usually seem to be faster than container maps. Plus, as already mentioned in the question, the key
of a container map can be any single value, while for structs it has to be a string.
Functionality wise, the containers.Map
is almost a generalization of struct
, i.e.:
containers.Map
are not limited to be valid identifiers strings.containers.Map
values can be enforced.One notable difference is that instances of containers.Map
are passed by reference, whereas struct
objects are passed by value.
Design wise, containers.Map
were introduced to fill the gap with java.util.Map
(see Using Java Collections in Matlab). This somehow explains the different pass-by convention, because all instances of Java Object
are passed by reference in Matlab (see Pass Data to Java Methods).
History wise, containers.Map
came in R2008b, i.e. after struct
, which came before R2006a.
After reading @hbaderts's answer, it got me wondering what the speed difference actually is. Hence, I went ahead and tried some benchmark test.
%% Below is to test read/write speed of struct, hashMap, and hashMap matrix assignment
numTrials= 10;
numKeys= 10000;
hw= zeros(1,numTrials);
hr= zeros(1,numTrials);
hmw= zeros(1,numTrials);
hmr= zeros(1,numTrials);
sw= zeros(1,numTrials);
sr= zeros(1,numTrials);
str= cell(1,numTrials);
for z= 1:numTrials
for e=1:numKeys
str{e}= strcat('adc',num2str(e));
end
% HashMap write
tic;
m= containers.Map();
for a=1:numKeys
m(str{a})=str{a};
end
hw(z)= toc;
% HashMap read
tic;
for b=1:numKeys
m(str{b});
end
hr(z)= toc;
% HashMap matrix write
tic;
keyval= cell(numKeys,1);
for a=1:numKeys
keyval{a}=str{a};
end
mm= containers.Map(keyval,keyval);
hmw(z)= toc;
% HashMap matrix read
tic;
for b=1:numKeys
mm(str{b});
end
hmr(z)= toc;
% Struct write
tic;
s= struct();
for c=1:numKeys
s.c.s.x.(str{c})= str{c};
end
sw(z)= toc;
% Struct read
tic;
for d=1:numKeys
s.c.s.x.(str{d});
end
sr(z)= toc;
end
fprintf('hashmap read time\n avg: %.3f seconds\n max: %.3f seconds\n',sum(hr)/numTrials,max(hr));
fprintf('hashmap write time\n avg: %.3f seconds\n max: %.3f seconds\n',sum(hw)/numTrials,max(hw));
fprintf('hashmap matrix read time\n avg: %.3f seconds\n max: %.3f seconds\n',sum(hmr)/numTrials,max(hmr));
fprintf('hashmap matrix write time\n avg: %.3f seconds\n max: %.3f seconds\n',sum(hmw)/numTrials,max(hmw));
fprintf('struct read time\n avg: %.3f seconds\n max: %.3f seconds\n',sum(sr)/numTrials,max(sr));
fprintf('struct write time\n avg: %.3f seconds\n max: %.3f seconds\n',sum(sw)/numTrials,max(sw));
Result:.
hashmap read time
.
avg: 0.301 seconds.
max: 0.320 seconds.
hashmap write time
.
avg: 0.233 seconds.
max: 0.247 seconds.
hashmap matrix read time
.
avg: 0.305 seconds.
max: 0.323 seconds.
hashmap matrix write time
.
avg: 0.011 seconds.
max: 0.016 seconds.
struct read time
.
avg: 0.059 seconds.
max: 0.066 seconds.
struct write time
.
avg: 0.040 seconds.
max: 0.046 seconds.
Let me know if this test looks valid!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With