A*1 and A+0 could be faster.

5 views (last 30 days)
Catalytic
Catalytic on 1 Jul 2022
Edited: Matt J on 3 Jul 2022
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
Elapsed time is 0.040498 seconds.
tic; A+0; toc
Elapsed time is 0.045996 seconds.
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
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
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)
ans = 0.0109
timeit(@()B*A)
ans = 0.0105

Sign in to comment.

Accepted Answer

Matt J
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:'
General Case:
w=rand(N,1);
W=SmartOperand(w);
executeIt(w,W,A)
Elapsed time is 0.019045 seconds. Elapsed time is 0.018784 seconds.
ans = logical
1
disp 'Special Case:'
Special Case:
w=1;
W=SmartOperand(w);
executeIt(w,W,A)
Elapsed time is 0.015762 seconds. Elapsed time is 0.000219 seconds.
ans = logical
1
function executeIt(w,W,A)
tic
Q1=w.*A;
toc
tic;
Q2=W.*A;
toc
isequal(Q1,Q2)
disp ' '
end
  2 Comments
Catalytic
Catalytic on 2 Jul 2022
Thanks @Matt J. That might be the best I can hope for. One thing I'd point out is that instead of testing obj.val==1 in your classdef, it would be better to have isequal(obj.val,1). Otherwise, the if stantement doesn't handle vector-valued obj.val correctly.
Matt J
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.

Sign in to comment.

More Answers (0)

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!