Reputation: 30674
Suppose we have a loop:
for i = 1:1000
A
B
C
end
... and I wish to find out the CPU usage spread.
A, B, C are MatLab statements not functions, so (IIUC) I can't use the profiler.
Also in reality I have a dozen lines to cover.
The obvious long-winded way would be:
s = zeros(50, 1);
t = cputime;
for ...
A
s(1) = s(1) + (cputime-t); t = cputime;
B
s(2) = s(2) + (cputime-t); t = cputime;
:
... which isn't too bad, I suppose.
But can it be improved upon?
I thought of doing:
t = zeros(50, 1);
e(t,0); % reset
for i = 1:1000
A
e(1);
B
e(2);
C
e(3);
end
... with:
function e(t, k)
if k==0
last_cputime = cputime;
return
end
t(k) = t(k) + (cputime-last_cputime);
last_cputime = cputime;
end
But it doesn't see t
, so I have to pass that.
Also it doesn't remember last_cputime
between invocations, so I need to pass that as well.
So e(last_cputime,t,1)
It's rather ugly. I experimented with using an in-line function:
e = @(k) eval( 't(k) = t(k) + (cputime-last_cputime); cputime = last_cputime;' );
But I couldn't get this working either:
K>> t = zeros(3,1)
t =
0
0
0
K>> eval( 't(1) = 3' )
t =
3
0
0
K>> e = @(k) eval( 't(k) = 3;' )
e =
function_handle with value:
@(k)eval('t(k) = 3;')
K>> e(1)
Attempt to add "t" to a static workspace.
See Variables in Nested and Anonymous Functions.
Error in pi_test>@(k)eval('t(k) = 3;')
I wonder if another option might be:
for i = 1:1000
e('A');
e('B');
e('C');
end
But then how to code up e
?
Is there any way to do avoid horrible ugliness-through-duplication?
Upvotes: 1
Views: 202
Reputation: 1845
How about a classdef that handles this?
You can save this as mtime.m
classdef mtime < handle
properties
times
end
properties (Access = private)
t
end
methods
function obj = mtime() %initialize
obj.t=cputime;
obj.times=[];
end
function time(obj)
obj.times(end+1) = cputime-obj.t;
obj.t = cputime;
end
end
end
You can then intialize with T=mtime();
and time your code by calling time(T);
After the code is finished the timings can be found in T.times
.
Upvotes: 1