how to write the right code to measure the elapsed time of this method d1 = diag(1./diag(A))
2 次查看(过去 30 天)
显示 更早的评论
how to write the right code to measure the elapsed time of this method
d1 = diag(1./diag(A))
0 个评论
回答(2 个)
John D'Errico
2024-6-23
编辑:John D'Errico
2024-6-23
Why do you care? The computations will be almost inifinitessimal, even for a huge matrix. (Do you understand the notation O(n)?) There are only n operations to be performed here, so O(n). The only cost as the matrix gets large will be allocating and storing the array, almost all of which will be zeros.
A = rand(10000);
timeit(@() diag(1./diag(A)))
More important may be what are you doing with that matrix! The result will be a diagonal matrix. And almost the only reason you are doing that is to multiply it with another matrix. And there are better ways to do that operation! The point is, a matrix multiply scales the rows (or columns as you do it) of the final array. But a matrix multiply is the expensive part. For example...
A = rand(5000);
B = rand(5000);
Adiag = 1./diag(A);
d = diag(1./diag(A));
timeit(@() B*d)
timeit(@() B.*Adiag.')
Why are the two results that much different? THINK ABOUT IT! What is the time cost for a matrix multiply of two nxn matrices? If you don't know, then you really need to do some reading. Hint: O(n^3)
But all you want to do is perform n^2 multiplies. What is the time cost of the second form I show? HInt: O(n^2)
My point is, if you are asking this question, it is most likely you are asking the wrong question. Just because you CAN scale the rows or coluns of matrix by a constant does not mean that a good way to accomplish the task by using a matrix multiply with a diagonal matrix. And just because you see it written in a formula does not mean you should always write code that looks just like your equation. At least, that is if you care about speed.
1 个评论
Matt J
2024-6-23
If you want the convenience of scaling row and columns with matrix-multiplication notation, using spdiag() might be a tolerable compromise,
A = rand(8000);
B = rand(8000);
Adiag = 1./diag(A);
d = diag(1./diag(A));
ds= diagsp(1./(diag(A)));
timeit(@() diag(1./diag(A)))
timeit(@() diagsp(1./diag(A)))
timeit(@() B*d)
timeit(@() B*ds)
timeit(@() B.*Adiag.')
function D=diagsp(v)
N=numel(v);
D=spdiags(v,0,N,N);
end
David Goodmanson
2024-6-23
编辑:David Goodmanson
2024-6-23
Hi Amna,
A common way to do this is with tic and toc. So:
a = rand(1e4,1e4);
tic
b = diag(1./diag(a));
toc
Elapsed time is 0.018291 seconds.
Not so much with this particular calculation, but there tends to be variation in the time reported by tic and toc. To average this out, you can put the calculation into a do-nothing-else for loop (being careful not to put the calculation of 'a' inside the loop):
a = rand(1e4,1e4);
tic
for k = 1:200
b = diag(1./diag(a));
end
toc
Elapsed time is 3.527247 seconds.
i.e. .0176 sec per operation
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Performance and Memory 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!