What extra data is stored by an anonymous function?
Afficher commentaires plus anciens
I have learned recently, that anonymous functions can carry around large amounts of extra data from the workspace that they don't use, even if this data is created after the anonymous function. The following example, together with the FUNCTIONS comand, illustrates this,
function fun=test
a=1;
b=2;
c=3;
fun=@(x)x+b+a;
a=7;
b=rand(1000);
c=5;
q=3;
r=4;
end
Now, back in the base workspace, when I apply the functions() command to 'fun', I see
>> fun=test; s=functions(fun); s.workspace{:}
ans =
b: 2
a: 1
ans =
fun: @(x)x+b+a
a: 1
b: [1000x1000 double]
c: 3
I would like to understand (with official documentation if possible) what rules anonymous functions use to decide what data to carry around. The above seems to suggest that s.workspace{1} will always contain the external variables and their values that the anonymous function actually uses. Meanwhile s.workspace{2} seems to contain updates to variables that came into scope before fun was defined. Am I correct that these are the rules? But if so, then why, in the above, does s.workspace{2} contain an update to b, but not to a and c?
Réponse acceptée
Plus de réponses (2)
3 commentaires
Philip Borghesani
le 5 Mar 2014
Try your function with this code and examine workspace{2} after calling fun
function fun=test
r=1;
fun=@(x) nest(x+r);
function out=nest(x)
r=r+1;
out=r+x;
end
end
Matt J
le 6 Mar 2014
Philip Borghesani
le 6 Mar 2014
I can't guarantee it but I believe you are correct, workspace{2} is only needed with nested functions.
James Tursa
le 6 Mar 2014
Modifié(e) : James Tursa
le 6 Mar 2014
This topic has already been addressed in this thread:
For convenience I will repeat my answer here:
When you create an anonymous function handle, all variables that are not part of the argument list are regarded as constants. Shared data copies of them are made at the time you create the function handle and actually stored inside the function handle itself. They retain their value and use up memory even if you change the source of the "constant" later on in your code. E.g., if you had done this:
A = v;
f = @(x) A*x; % could have done f = @(x) v*x; and got same result
A = 2*v;
the last line has no effect on the function handle f output (EDIT). Note that if A happens to be a very large variable, its memory effectively gets "locked up" inside f and can only be cleared by clearing (or re-defining) f. E.g., in the above code snippet, the 2nd line will put a shared data copy of A inside of f. The 3rd line will cause this shared data copy to essentially become a deep data copy (it gets unshared with A at that point).
Bottom line is, once the anonymous function gets created the standard rules for shared data copies applies. At least that was the behavior I observed last year. I may need to re-examine this ...
6 commentaires
James Tursa
le 6 Mar 2014
Modifié(e) : James Tursa
le 6 Mar 2014
What version of MATLAB and OS are you running? In my versions (Win32 R2013a and Win64 R2012a) the behaviour is as I posted for the expression shown ... a large 2nd variable does not get saved to the mat file. I also ran the exact case in your FEX submission and got the same result ... the large 2nd variable does not get saved to the mat file. So perhaps the behavior of "save" or anonymous functions has recently changed, or maybe it's an OS issue. Offhand, saving variables that are not used by a function handle to a mat file would seem to be a "save" undesired new feature.
I will have to look at the nested function example above in more detail to see what is going on in that case.
James Tursa
le 6 Mar 2014
I was being naive. To be explicit, I executed the code in your FEX submission and the first mat file, tst1, did NOT get the large variable written to it, contrary to what I was expecting per your description. So I assumed it was a version or OS issue. However, I had just copied and pasted the innards of the function into the MATLAB command window. When I actually created the function and executed the code, voila, large file. So the behavior is apparently altered by the fact that the code is inside a function. Seems like an undesireable feature to me, but it is what it is.
Also, to be clear, everything I have written above is still correct if my words "has no effect on the function handle f" are replaced by "has no effect on the function handle f output", which was the meaning I originally intended by the phrase. All of the shared data copy stuff I wrote about above is still true.
James Tursa
le 6 Mar 2014
Agreed.
Catégories
En savoir plus sur Workspace Variables and MAT Files dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!