timing code in matlab

2019-01-07 23:11发布

I have written down a function in 4 different ways and I want to time it .

Up-to now I have been doing this thing :

tic
%//function 1
toc

tic
%//function 2
toc

tic
%//function 3
toc

tic
%//function 4
toc

But now I want to compute the timing data for each function for (say 100 times) each and then compute the average time spent on each function. How can I do so?

Also I read somewhere that the time printed is the elapsed “wall clock” time – so it will be affected by whatever else my computer is doing whilst the MATLAB program was running.

So is there a better way of doing it ?? I have heard there is a MATLAB built in code-profiler with the command "profile on". Please can anyone suggest me the way in which I can use it?

I have also consulted the sites : Timing code in MATLAB and Profiler to find code bottlenecks.

Please suggest how to do this many times in a loop. Thanks in advance.

EDIT: 23rd Sept 2013: By following everyone's suggestions I did this : My functions are defined as one, two, three & four.

function [] = one(x)
I = imread('coins.png');
I = double(I);
I = imresize(I,[x x]);
sig=.8;    % scale parameter in Gaussian kernel
G=fspecial('gaussian',15,sig); % Caussian kernel
Img_smooth=conv2(I,G,'same');  % smooth image by Gaussiin convolution
[Ix,Iy]=gradient(Img_smooth);
f=Ix.^2+Iy.^2;
g=1./(1+f);  % edge indicator function.
end

function [] = two(x)
I = imread('coins.png');
I = double(I);
I = imresize(I,[x x]);
sig=.8;    % scale parameter in Gaussian kernel
G=fspecial('gaussian',15,sig); % Caussian kernel
Img_smooth=imfilter(I,G,'conv');  % smooth image by Gaussiin convolution
[Ix,Iy]=gradient(Img_smooth);
f=Ix.^2+Iy.^2;
g=1./(1+f);  % edge indicator function.
end

function [] = three(x)
I = imread('coins.png');
I = double(I);
I = imresize(I,[x x]);
sig=.8;    % scale parameter in Gaussian kernel
G=fspecial('gaussian',15,sig); % Caussian kernel
%//Trying to use 1D convolution instead of using 2D convolution
[U,S,V] = svd(G);
K1 = U(:,1) * sqrt(S(1,1));
K2 = V(:,1)' * sqrt(S(1,1));
KI1 = imfilter(I,K1,'conv');                            
Img_smooth = imfilter(KI1,K2,'conv');    % smooth image by Gaussiin convolution
[Ix,Iy]=gradient(Img_smooth);
f=Ix.^2+Iy.^2;
g=1./(1+f);  % edge indicator function.
end

function [] = four(x)
I = imread('coins.png');
I = double(I);
I = imresize(I,[x x]);
sig=.8;    % scale parameter in Gaussian kernel
G=fspecial('gaussian',15,sig); % Caussian kernel
%//Trying to use 1D convolution instead of using 2D convolution
[U,S,V] = svd(G);
K1 = U(:,1) * sqrt(S(1,1));
K2 = V(:,1)' * sqrt(S(1,1));
KI1 = imfilter(I,K1,'conv');                            
Img_smooth=conv2(K1,K2,I,'same');  % smooth image by Gaussiin convolution
[Ix,Iy]=gradient(Img_smooth);
f=Ix.^2+Iy.^2;
g=1./(1+f);  % edge indicator function.
end

I then ran this program and got this times :

clc;clear all;close all;
x=64;N=100;
tic
for i=1:N
    one(x);
end
toc

tic
for i=1:N
    two(x);
end
toc

tic
for i=1:N
    three(x);
end
toc

tic
for i=1:N
    four(x);
end
toc

The times I got are :

%//x=64;N=100;
Elapsed time is 0.898583 seconds.
Elapsed time is 0.983132 seconds.
Elapsed time is 0.921140 seconds.
Elapsed time is 0.811144 seconds.

%//x=128;N=100;
Elapsed time is 0.990136 seconds.
Elapsed time is 1.044167 seconds.
Elapsed time is 0.999153 seconds.
Elapsed time is 1.005903 seconds.

%//x=256;N=100
Elapsed time is 1.495068 seconds.
Elapsed time is 1.416523 seconds.
Elapsed time is 1.462653 seconds.
Elapsed time is 1.605767 seconds.

%//x=1024;N=100
Elapsed time is 16.681720 seconds.
Elapsed time is 14.857957 seconds.
Elapsed time is 15.580161 seconds.
Elapsed time is 19.140707 seconds.

Is my timing code wrong ? I mean technically I should be getting the fastest times for the function three & four always. For different values of x , I am getting different results.

Please guys could you suggest me a better timing measurement approach ?? Thanks in advance!

3条回答
贼婆χ
2楼-- · 2019-01-07 23:42

Using the profiler is almost as simple as tic/toc:

profile on;
for i=1:N
    your_function()
end
profile viewer;

If your 4 functions are independent and don't influence each other, you can also profile all of them in one block:

profile on;
for i=1:N
    your_function1()
    your_function2()
    your_function3()
    your_function4()
end
profile viewer;

The profiler will let you have a look at the processing times for each single line of code. You can either benchmark wall-clock or cpu-time, the default is cpu-time. See the profile documentation for how to change that.

EDIT: What I like about the profiler is, that it gives you a breakdown of each subfunction's processing time - hence it's a great way to spot bottlenecks in larger processes. That's probably not so much the use case here.

查看更多
Luminary・发光体
3楼-- · 2019-01-07 23:46

The profiler is one possibility, but it will slow down your code significantly. Alternatively you could store the toc value within your loop or after every function call.

t(i) = toc

and then compare these values, compute the mean or whatever, like you would deal with other vectors.

查看更多
三岁会撩人
4楼-- · 2019-01-07 23:56

The best way to time MATLAB code is to use timeit, available from the MATLAB Central File Exchange.

It was implemented by Steve Eddins, one of the senior developers at MathWorks, and it takes care of a lot of subtleties in timing your code. For example, code runs very differently when it's executed within a function rather than within a script, and it needs to have a couple of "warm-up" runs in order to take proper advantage of the JIT compiler. It will also run the code many times in a loop, and take the median.

These things are difficult to get right without knowing a fair amount about how MATLAB works under the hood, and timeit takes care of these things for you - simple applications of tic and toc do not.

Using the profiler, as other answers have suggested, is problematic as it switches off many aspects of the JIT compiler, and will not run at the same speed as it does normally. Profiler does a great job of telling you which portions of your code take a relatively large proportion of time, i.e. discovering bottlenecks, but it's not intended for giving you actually realistic timings.

Note that in the most recent version (R2013b), timeit is available as part of core MATLAB, and does not need to be obtained from the File Exchange.

For example, to time your function one with the input argument x equal to 64, you would type:

myfun = @()one(64);
timeit(myfun);

What this does is to make a function handle to your function one (which makes sure that the code is executed inside a function, important as mentioned above), then passes this function handle into timeit. The output is timeit's estimate of the time taken to execute the code.

查看更多
登录 后发表回答