matlab中的计时代码

时间:2013-09-23 05:54:00

标签: performance matlab timer

我已经用4种不同的方式记下了一个功能,我想要计时。

到目前为止,我一直在做这件事:

tic
%//function 1
toc

tic
%//function 2
toc

tic
%//function 3
toc

tic
%//function 4
toc

但是现在我想计算每个函数的计时数据(比如说100次),然后计算每个函数花费的平均时间。我怎么能这样做?

此外,我在某处读到打印的时间是经过的“挂钟”时间 - 所以当MATLAB程序运行时,它会受到我的计算机正在做的其他事情的影响。

那么有更好的方法吗?我听说有一个MATLAB内置的代码分析器,命令为“profile on”。请有人建议我使用它的方式吗?

我还咨询了网站:Timing code in MATLABProfiler to find code bottlenecks

请建议如何在循环中多次执行此操作。提前致谢。

编辑:2013年9月23日:按照每个人的建议,我这样做了: 我的功能定义为一,二,三和四。

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

然后我运行了这个程序并得到了这个时间:

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

我得到的时间是:

%//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.

我的计时代码错了吗?我的意思是技术上我应该获得功能三和最快的时间。总是四个。对于x的不同值,我得到不同的结果。

请大家你能给我一个更好的时间测量方法吗? 提前谢谢!

3 个答案:

答案 0 :(得分:14)

为MATLAB代码计时的最佳方法是使用MATLAB Central File Exchange提供的timeit

它是由MathWorks的高级开发人员之一Steve Eddins实现的,它在处理代码时需要考虑很多细微之处。例如,代码在函数内而不是在脚本中执行时运行方式非常不同,并且需要进行一些“预热”运行才能正确利用JIT编译器。它还会在循环中多次运行代码,并取中位数。

如果不了解MATLAB如何在幕后工作,并且timeit为您处理这些事情 - tic和{{1}的简单应用程序,这些事情很难做到。不要。

正如其他答案所暗示的那样,使用分析器是有问题的,因为它关闭了JIT编译器的许多方面,并且不会以与正常情况相同的速度运行。 Profiler可以很好地告诉你代码的哪些部分占用相对较长的时间,即发现瓶颈,但它并不是为了给你真正实际的时间安排。

请注意,在最新版本(R2013b)中,toc作为核心MATLAB的一部分提供,不需要从文件交换中获取。

例如,要使用输入参数timeit等于64的函数one计时,可以输入:

x

这样做是为函数myfun = @()one(64); timeit(myfun); 创建一个函数句柄(这确保代码在函数内部执行,如上所述很重要),然后传递此函数处理one。输出是timeit估计执行代码所花费的时间。

答案 1 :(得分:3)

分析器是一种可能性,但它会显着减慢代码速度。 或者,您可以将toc值存储在循环中或每次函数调用之后。

t(i) = toc

然后比较这些值,计算均值或其他值,就像处理其他向量一样。

答案 2 :(得分:1)

使用分析器几乎与tic / toc一样简单:

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

如果您的4个功能是独立的并且不会相互影响,您也可以在一个区块中对所有这些功能进行分析:

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

通过分析器,您可以查看每行代码的处理时间。 您可以对挂钟或cpu-time进行基准测试,默认为cpu-time。有关如何更改的信息,请参阅profile文档。

编辑: 我对分析器的喜好是,它为您提供每个子功能处理时间的细分 - 因此它是发现大型流程瓶颈的好方法。 这可能不是这里的用例。