A*1 and A+0 could be faster.
1 view (last 30 days)
Show older comments
Regardless of the size of a matrix A, operations A*1 and A+0 should be very fast. A simple pre-check would detect if one of these special cases being executed and determine that the result can be obtained trivially, without any actual number crunching. However, these pre-checks don't appear to be implemented -
A=rand(5000);
tic; A*1; toc
tic; A+0; toc
Is it because of some less than obvious practical difficulty, or am I just the first one to think of this?
14 Comments
Bruno Luong
on 2 Jul 2022
"We are supposing that the user knows, and can therefore expect MATLAB to use (:) optimally"
I did but I'm pretty much let down when I discover the column (:) does more and pretty much useless copy/rearange data.
Since then I use reshape and avoid using (:) when I can.
I guess it is too late for TMW to change the behavioir of (:) because it would break the compatibility. I'm ot sure what they promises to Matt's request,I doubt it will be fixed one day.
Also with all due respect to Matt, his solution actually did not answer your question, he merely put the check you did on a class, so it is like you code, just the check is hidden but still there.
I bet you would still hesitate to use his solution since it will cost some extra overhead, and will not have MATLAB optimization;
A=rand(1000);
B=SmartOperand(A);
tic; A'*A; toc % Elapsed time is 0.010679 seconds.
tic; B'*B; toc % Elapsed time is 0.020017 seconds.
At the end you would still ask the question whereas you would use depending on the size of the vector/matrix and what you would do with it.
Matt J
on 3 Jul 2022
Edited: Matt J
on 3 Jul 2022
Also with all due respect to Matt, his solution actually did not answer your question, he merely put the check you did on a class, so it is like you code, just the check is hidden but still there.
It doesn't answer the question (only MathWorks can speak to their software design decisions), but the solution does permit the syntax @Catalytic wanted to use, rather than explicit if statements.
I bet you would still hesitate to use his solution since it will cost some extra overhead, and will not have MATLAB optimization;
The classdef hasn't been optimized for the case where both of the operands are SmartOperand objects. I didn't think that was a likely use case. The following is a more representative version of the test. Oddly, I consistently find that SmartOperand is even a little bit faster than the built-in version, though not by a very significant amount.
A=rand(1000);
B=SmartOperand(A);
timeit(@()A*A)
timeit(@()B*A)
Accepted Answer
Matt J
on 1 Jul 2022
Edited: Matt J
on 2 Jul 2022
My sense of things is that, in the situations where you would care about such special case optimizations, you would know in advance that A will be large. One possible workaround to get the benefits that you're talking about would therefore be to use a special container class like the attached in those situations.
By overloading the times() (or plus()), you can implement the pre-checks that you want. There is some overhead introduced by going through Matlab's M-coded OOP framework. However, because we anticipate A to be large, the overhead should be negligible, as in the following example test:
N=1e4;
A=rand(N,1e3);
disp 'General Case:'
w=rand(N,1);
W=SmartOperand(w);
executeIt(w,W,A)
disp 'Special Case:'
w=1;
W=SmartOperand(w);
executeIt(w,W,A)
function executeIt(w,W,A)
tic
Q1=w.*A;
toc
tic;
Q2=W.*A;
toc
isequal(Q1,Q2)
disp ' '
end
2 Comments
Matt J
on 2 Jul 2022
You're right, I fixed it, and also added overloads for some other operators (and,or,plus, mtimes).
If this suits your needs, please Accept-click.
More Answers (0)
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!