Matlab中的定时代码

6

我已经用四种不同的方式编写了一个函数,并希望对其进行计时。

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

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
请建议如何在循环中多次执行此操作。提前感谢您的回答。

1
如果您担心(短)进程会干扰您的测量结果,通常最好查看时间中位数而不是平均值。 - Dennis Jaheruddin
我撤销了您的最后一次编辑,我认为它混淆了这个问答的重点,否则很好。关于该编辑中的问题(如果仍然有用):imfilter 会尽可能地分离内核(您可以 edit 查看代码),conv2 也可能会这样做,但不确定。无论如何,执行时间似乎受到图像加载时间的影响,您应该从计时中排除它。 - Cris Luengo
3个回答

17

使用timeit是测量MATLAB代码时间的最佳方法,它可从MATLAB Central File Exchange下载。

此工具由MathWorks的高级开发人员Steve Eddins实现,并处理了许多细节。例如,代码在函数内和脚本内执行时运行非常不同,需要进行几次“热身”才能充分利用JIT编译器。它还会在循环中多次运行代码并取中位数。

这些细节如果不了解MATLAB的内部工作原理很难正确处理,而timeit可为您处理这些细节——简单应用tictoc无法做到这一点。

正如其他答案所建议的那样,使用分析器存在问题,因为它会关闭JIT编译器的许多方面,并且速度不会与平常运行一样。分析器可以告诉您哪些部分的代码占用了相对较大的时间比例,即发现瓶颈,但它并不适用于提供实际的定时。

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

例如,要计算输入参数x等于64的函数one的时间,您可以键入:

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

这样做的作用是为你的函数one创建一个函数句柄(确保代码在函数内执行,如上所述非常重要),然后将此函数句柄传递给timeit。输出是timeit估计执行代码所需的时间。


1
我刚刚查看了你的编辑,其中包含函数 onetwo 等。如果以后在实际使用这些函数时,你需要一些它们的输出结果,那么你应该真正计算它们返回输出参数所需的时间。 - Sam Roberts
我的所有函数都返回相同的输出。那么有必要在返回输出时计时我的函数吗?它们会显示差异吗? - roni
1
如果它们都返回相同的输出参数,那么它可能不会显着影响相对时间 - 它应该对每个人产生相同的影响。但总的来说,尽量按实际使用的方式计时,因为不明显哪些东西将成为瓶颈。 - Sam Roberts
+1: :)) 谢谢,我接受了你的答案。顺便问一下,你能告诉我如何在 Matlab 中更快地计算二维图像的梯度吗?据我了解,Matlab 的 gradient 命令效率相当低下。我实际上是在这里找到的:http://regularize.wordpress.com/2013/06/19/how-fast-can-you-calculate-the-gradient-of-an-image-in-matlab/ - roni
1
@roni,请提出一个单独的问题,我们会尝试回答。 - Sam Roberts
请查看以下链接:https://dev59.com/KXfZa4cB1Zd3GeqPOCh2 - roni

3

使用分析器是一种可能性,但它会显著减慢您的代码。相反,您可以在循环内部或每次函数调用之后存储toc值。

t(i) = toc

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

1
它分析的不仅仅是简单的时间流逝,而且已经评估了确定的时间跨度。但也许你不需要进一步的计算,因为分析器提供了你所需的所有信息。试试吧 ;) - Robert Seifert
1
分析器会减慢您的代码,因为(为了逐行计时您的代码并提供其他诊断信息),它需要关闭JIT编译器的各个方面。 - Sam Roberts
1
@roni 只需考虑使用分析器来给出上限。如果一行代码很慢,您总是可以通过分析器找到它,但有时看起来很慢的东西实际上在不使用分析器的情况下可以加速运行。--- 就其价值而言,尽管正常运行和使用分析器之间可能存在差异,但分析器始终会指向正确的瓶颈。 - Dennis Jaheruddin
1
@roni 当然可以。可以这样想,早期版本的MATLAB是一种纯解释型语言,也就是说它会逐行执行你的代码,然后再转到下一行。在更近期的版本中,它会在运行时查看你的代码,并预编译其中的一些部分,以便更快地运行。这被称为即时编译或JIT编译。当你使用分析器时,为了生成报告,它需要逐行提供信息,因此需要关闭一些JIT功能。(续...) - Sam Roberts
1
@roni(...)因此,您的代码运行速度较慢。它不仅运行速度较慢,而且不同的事物会比其他事物更加缓慢,因此这不是比较两个不同事物的好方法。 - Sam Roberts
显示剩余7条评论

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 时间进行基准测试,默认为 CPU 时间。有关如何更改它的详细信息,请参阅profile文档。

编辑: 我喜欢分析器的原因是,它可以给出每个子函数的处理时间的细分 - 因此,这是发现较大过程中瓶颈的好方法。在这里可能不是很适用。


3
分析器的一个主要问题是它会关闭JIT加速器。 - StrongBad
@DanielE.Shub 嗯,谢谢!Sam在他的帖子中也向我解释了这个问题!那么timeit比tic-toc更好吗?请给出您对etime的命令建议。 - roni
2
@roni 你不需要etime来计时。它最多只能给你与tictoc相同的结果。通常情况下,tictoc用于快速检查,而timeit可以提供更好的结果。但是,如果你有许多行代码并想快速查看哪些行需要较长时间,可以使用分析器。 - Dennis Jaheruddin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接