What extra data is stored by an anonymous function?
조회 수: 14 (최근 30일)
이전 댓글 표시
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?
댓글 수: 0
채택된 답변
Philip Borghesani
2014년 2월 10일
편집: Philip Borghesani
2014년 2월 10일
I will start my answer with a quote from the documentation of functions:
The functions function is used for internal purposes, and is provided
for querying and debugging purposes. Its behavior may change in
subsequent releases, so it should not be relied upon for programming
purposes.
The output from this function for this code WILL change in a future version of MATLAB and can change in your current version:
>> 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
>> feature accel off
>> fun=test; s=functions(fun); s.workspace{:}
ans =
b: 2
a: 1
ans =
fun: @(x)x+b+a
a: 7
b: [1000x1000 double]
c: 5
q: 3
r: 4
workspace{2} will contain the final state of the function workspace at exit but might not take into consideration non-visible changes to that workspace that are optimized by the jit.
The contents of workspace{2} should be considered completely version dependent and subject to removal or being inconsistent due to current and future optimizations.
댓글 수: 3
Philip Borghesani
2014년 2월 11일
Anything returned by functions or even the existence of the function functions is subject to change but the contents or existence of workspace{2} is known to change. There is a slight difference there.
One note on the contents you are seeing of workspace{2}. This is not a copy of variables in the function but a pointer to the actual workspace. Nested functions or multiple anonymous functions will see the same values in workspace{2} even if they are changed by a nested function so the memory used is not usually noticed and there is little performance overhead caused by this data as long as parfor is not in the equation.
추가 답변 (2개)
Matt J
2014년 3월 4일
편집: Matt J
2014년 3월 4일
댓글 수: 3
Philip Borghesani
2014년 3월 6일
I can't guarantee it but I believe you are correct, workspace{2} is only needed with nested functions.
James Tursa
2014년 3월 6일
편집: James Tursa
2014년 3월 6일
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
참고 항목
카테고리
Help Center 및 File Exchange에서 Workspace Variables and MAT Files에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!