Does struct manipulation work in place when using arrayfun on an array of structs?
1 Ansicht (letzte 30 Tage)
Ältere Kommentare anzeigen
Charles Refvem
am 19 Apr. 2024
Bearbeitet: Matt J
am 20 Apr. 2024
I would like to better understand how arrays of structured data are handled when they are manipulated using arrayfun. I've created a minimal example below to show the kind of situation I'm looking at. In this example, I'm applying a function to each struct in an array of structs using arrayfun to manipulate the structures by adding an additional field. Does this code work "in place" on the structs in the array, only allocating new memory for the new field? If this will copy the structures (or the entire array) as the fields are added, then it seems better to use a loop than arrayfun. I'd appreciate any insight into how the memory is managed during this kind of operation.
s = struct("x", {1, 2, 3});
s = arrayfun(@update, s);
function s = update(s)
s.y = s.x^2;
end
0 Kommentare
Akzeptierte Antwort
Matt J
am 19 Apr. 2024
Bearbeitet: Matt J
am 19 Apr. 2024
It does indeed appear that with arrayfun (unlike loops), pre-existing field contents get deep-copied to a new memory address (as indicated by pr in the results below):
s= struct("x", {1:5,2:6,3:7});
u=s; for i=1:numel(s), u(i).y=u(i).x.^2; end %loop copy
v=arrayfun(@update, s); %arrayfun copy
format debug
s(3).x
ans =
Structure address = 1ab51ab5120
m = 1
n = 5
pr = 1ab6b9a1d80
3 4 5 6 7
u(3).x
ans =
Structure address = 1ab51ab5120
m = 1
n = 5
pr = 1ab6b9a1d80
3 4 5 6 7
v(3).x
Structure address = 1ab4d81f7c0
m = 1
n = 5
pr = 1ab6d5f5500
3 4 5 6 7
function s = update(s)
s.y = s.x.^2;
end
3 Kommentare
Steven Lord
am 19 Apr. 2024
Your function may be simpler and faster than arrayfun, but it doesn't do everything arrayfun does.
x = [1:5 -1];
y = arrayfun(@realsqrt, x, ErrorHandler = @(varargin) NaN)
z = arrayfun(@ones, x, UniformOutput = false)
y2 = myArrayfun(@realsqrt, x)
It also lacks the capability to handle non-uniform outputs from the function (the 'UniformOutputs' name-value argument, see the creation of z above.) There are some circumstances where you may not need the full level of flexibility of arrayfun, and in those cases you can beat the performance of arrayfun.
function C=myArrayfun(fun,A)
C=repmat( fun(A(1)), size(A) );
for i=2:numel(C)
C(i)=fun(A(i));
end
end
Matt J
am 19 Apr. 2024
Bearbeitet: Matt J
am 20 Apr. 2024
but it doesn't do everything arrayfun does.
Yes, for the purposes of this example that's true, but I can't see why any of those additional features explain why deep copying of all the input array data is done by the native arrayfun. I feel like I could add those features to my version without the deep copying, and still see a performance benefit.
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Structures finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!