A*1 and A+0 could be faster.

4 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
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
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!