Unexpected slowdown using () indexing

조회 수: 5 (최근 30일)
Walter Roberson
Walter Roberson 2023년 1월 30일
댓글: James Lebak 2023년 2월 2일
format long g
NULL = 0; counter = 0; start = tic; while toc(start) < 10; NULL; counter = counter + 1; end; counter/10
ans =
3699475.2
NULL = @()0; counter = 0; start = tic; while toc(start) < 10; NULL(); counter = counter + 1; end; counter/10
ans =
2326610.7
NULL = 0; counter = 0; start = tic; while toc(start) < 10; NULL(); counter = counter + 1; end; counter/10
ans =
588245.3
NULL = 0; counter = 0; start = tic; while toc(start) < 10; NULL(1); counter = counter + 1; end; counter/10
ans =
2540740.2
Observe that referring to a variable in a loop can iterate millions of time per second, and executing an anonymous function to retrieve a value is (fewer) millions of times per second -- but that taking a plain scalar and using empty () to dereference it slows down to the hundreds-of-thousands range (roughly a factor of 7). But we can see that using (1) indexing is slightly slower than just using the variable with no () but is still comparable to no indexing in speed.
So there is something about using the empty index on a scalar that invokes much worse performance.
  댓글 수: 7
Bruno Luong
Bruno Luong 2023년 1월 31일
편집: Bruno Luong 2023년 1월 31일
I think the only justification existing of this strange empty indexing is when using with comma list that reduces to an empty cell
A=magic(2);
c=cell(0);
Aemptyidexing = A(c{:}) % equal to A() i.e. to A
%
But to me the value of A() == A is just an arbitrary design choice. I don't see any logical pattern with what come when the comma list is not empty.
To me this "feature" can be ignored; for good reason.
Personally I would prefer an error is thrown when empty indexing is encountered.
Walter Roberson
Walter Roberson 2023년 1월 31일
Looks like it triggers a copy!
format debug
NULL = 0
NULL =
Structure address = 7f077e274ee0 m = 1 n = 1 pr = 7f4605e12160 0
NULL
NULL =
Structure address = 7f077e412e00 m = 1 n = 1 pr = 7f076cc60240 0
NULL()
ans =
Structure address = 7f077e3376a0 m = 1 n = 1 pr = 7f077bc2e320 0

댓글을 달려면 로그인하십시오.

답변 (1개)

James Lebak
James Lebak 2023년 2월 1일
Paren-reference in many cases creates a copy. This is expected behavior.
NULL(1) is nearly as fast as NULL on a scalar because it's been specially optimized. NULL() is indexing with no indices (empty paren-reference). We allow this syntax because when NULL is a function handle, NULL() means to call the function with no arguments. But we don't consider it common usage, and we haven't optimized it. As you observed, it therefore creates an expensive copy. We could consider optimizing it in a future release. If you have a need for this operation to be performant we'd be interested to hear of it.
  댓글 수: 5
Walter Roberson
Walter Roberson 2023년 2월 2일
Interesting.
You mention that in the case of assigning a whole variable to another variable is faster in a script because it reduces to a trivial pointer copy. Trivial pointer copy makes sense it itself. But what extra work is being done in the function case? I could see a difference if the variable name was one of the parameters (in which case you have to worry about copy-on-write), but ....
Oh wait... is ans effectively a global variable?? (Mumble, mumble... No, I still can't explain the difference.)
James Lebak
James Lebak 2023년 2월 2일
Among other things, in functions we're handling an uninitialized LHS differently than we do in scripts. We may be able to do it faster than we are now. Like the empy paren-reference case, I don't think this is a very high priority case though.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Debugging and Analysis에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by