P i
P i

Reputation: 30674

How to time each line of a MatLab script?

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

Answers (1)

Gelliant
Gelliant

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

Related Questions