什么是Matlab的tic和toc函数的Python等价物?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是Matlab的tic和toc函数的Python等价物?相关的知识,希望对你有一定的参考价值。

什么是Matlab的tic and toc functions的Python等价物?

答案

除了ThiefMaster提到的timeit之外,一个简单的方法就是(在导入time之后):

t = time.time()
# do stuff
elapsed = time.time() - t

我有一个我喜欢使用的辅助类:

class Timer(object):
    def __init__(self, name=None):
        self.name = name

    def __enter__(self):
        self.tstart = time.time()

    def __exit__(self, type, value, traceback):
        if self.name:
            print('[%s]' % self.name,)
        print('Elapsed: %s' % (time.time() - self.tstart))

它可以用作上下文管理器:

with Timer('foo_stuff'):
   # do some foo
   # do some stuff

有时我发现这种技术比timeit更方便 - 这一切都取决于你想要测量的东西。

另一答案

Eli's answer更新为Python 3:

class Timer(object):
    def __init__(self, name=None, filename=None):
        self.name = name
        self.filename = filename

    def __enter__(self):
        self.tstart = time.time()

    def __exit__(self, type, value, traceback):
        message = 'Elapsed: %.2f seconds' % (time.time() - self.tstart)
        if self.name:
            message = '[%s] ' % self.name + message
        print(message)
        if self.filename:
            with open(self.filename,'a') as file:
                print(str(datetime.datetime.now())+": ",message,file=file)

就像Eli一样,它可以用作上下文管理器:

import time 
with Timer('Count'):
    for i in range(0,10_000_000):
        pass

输出:

[Count] Elapsed: 0.27 seconds

我还更新了它以打印报告的时间单位(秒)并修剪Can建议的位数,并且还可以附加到日志文件中。您必须导入datetime才能使用日志记录功能:

import time
import datetime 
with Timer('Count', 'log.txt'):    
    for i in range(0,10_000_000):
        pass
另一答案

在Stefan和antonimmo的答案的基础上,我结束了

def Tictoc():
    start_stack = []
    start_named = {}

    def tic(name=None):
        if name is None:
            start_stack.append(time())
        else:
            start_named[name] = time()

    def toc(name=None):
        if name is None:
            start = start_stack.pop()
        else:
            start = start_named.pop(name)
        elapsed = time() - start
        return elapsed
    return tic, toc

utils.py模块中,我使用它

from utils import Tictoc
tic, toc = Tictoc()

这条路

  • 你可以简单地使用tic()toc()并在Matlab中嵌套它们
  • 或者,您可以命名它们:tic(1)toc(1)tic('very-important-block')toc('very-important-block')和具有不同名称的计时器不会干扰
  • 以这种方式导入它们可防止使用它的模块之间的干

(此处toc不会打印已用时间,但会返回它。)

另一答案

当我从Matlab迁移到python时,我遇到了同样的问题。在这个线程的帮助下,我能够构建一个Matlab tic()toc()函数的精确模拟。只需在脚本顶部插入以下代码即可。

import time

def TicTocGenerator():
    # Generator that returns time differences
    ti = 0           # initial time
    tf = time.time() # final time
    while True:
        ti = tf
        tf = time.time()
        yield tf-ti # returns the time difference

TicToc = TicTocGenerator() # create an instance of the TicTocGen generator

# This will be the main function through which we define both tic() and toc()
def toc(tempBool=True):
    # Prints the time difference yielded by generator instance TicToc
    tempTimeInterval = next(TicToc)
    if tempBool:
        print( "Elapsed time: %f seconds.
" %tempTimeInterval )

def tic():
    # Records a time in TicToc, marks the beginning of a time interval
    toc(False)

而已!现在我们已经准备好像在Matlab中一样充分利用tic()toc()。例如

tic()

time.sleep(5)

toc() # returns "Elapsed time: 5.00 seconds."

实际上,这比内置的Matlab功能更通用。在这里,您可以创建另一个TicTocGenerator实例来跟踪多个操作,或者只是以不同的方式计时。例如,在对脚本进行计时时,我们现在可以单独为每个脚本以及整个脚本计时。 (我将提供一个具体的例子)

TicToc2 = TicTocGenerator() # create another instance of the TicTocGen generator

def toc2(tempBool=True):
    # Prints the time difference yielded by generator instance TicToc2
    tempTimeInterval = next(TicToc2)
    if tempBool:
    print( "Elapsed time 2: %f seconds.
" %tempTimeInterval )

def tic2():
    # Records a time in TicToc2, marks the beginning of a time interval
    toc2(False)

现在,您应该能够计算两个不同的东西:在下面的示例中,我们分别计算脚本的总脚本和部分时间。

tic()

time.sleep(5)

tic2()

time.sleep(3)

toc2() # returns "Elapsed time 2: 5.00 seconds."

toc() # returns "Elapsed time: 8.00 seconds."

实际上,你甚至不需要每次都使用tic()。如果您有一系列想要计时的命令,那么您可以编写

tic()

time.sleep(1)

toc() # returns "Elapsed time: 1.00 seconds."

time.sleep(2)

toc() # returns "Elapsed time: 2.00 seconds."

time.sleep(3)

toc() # returns "Elapsed time: 3.00 seconds."

# and so on...

我希望这有用。

另一答案

tic和toc的绝对最佳模拟是在python中简单地定义它们。

def tic():
    #Homemade version of matlab tic and toc functions
    import time
    global startTime_for_tictoc
    startTime_for_tictoc = time.time()

def toc():
    import time
    if 'startTime_for_tictoc' in globals():
        print "Elapsed time is " + str(time.time() - startTime_for_tictoc) + " seconds."
    else:
        print "Toc: start time not set"

然后你可以使用它们:

tic()
# do stuff
toc()
另一答案

通常,IPython的%time%timeit%prun%lprun(如果安装了line_profiler)可以很好地满足我的分析需求。然而,当我试图剖析交互式驱动的计算时,即用户在GUI中的鼠标移动时,出现了类似tic-toc功能的用例。我觉得在源代码中发送tics和tocs是垃圾邮件,而交互式测试则是揭示瓶颈的最快方法。我选择了Eli Bendersky的Timer课程,但并不完全满意,因为它要求我更改代码的缩进,这在某些编辑器中可能不方便并且会混淆版本控制系统。此外,可能需要测量不同函数中的点之间的时间,这对with语句不起作用。在尝试了很多Python的聪明之后,这是我发现最好的简单解决方案:

from time import time
_tstart_stack = []

def tic():
    _tstart_stack.append(time())

def toc(fmt="Elapsed: %s s"):
    print fmt % (time() - _tstart_stack.pop())

由于这可以通过在堆栈上推动开始时间来实现,因此它可以正确地用于多个级别的tics和tocs。它还允许我们更改toc语句的格式字符串以显示其他信息,我喜欢Eli的Timer类。

出于某种原因,我关注纯Python实现的开销,所以我也测试了一个C扩展模块:

#include <Python.h>
#include <mach/mach_time.h>
#define MAXDEPTH 100

uint64_t start[MAXDEPTH];
int lvl=0;

static PyObject* tic(PyObject *self, PyObject *args) {
    start[lvl++] = mach_absolute_time();
    Py_RETURN_NONE;
}

static PyObject* toc(PyObject *self, PyObject *args) {
return PyFloat_FromDouble(
        (double)(mach_absolute_time() - start[--lvl]) / 1000000000L);
}

static PyObject* res(PyObject *self, PyObject *args) {
    return tic(NULL, NULL), toc(NULL, NULL);
}

static PyMethodDef methods[] = {
    {"tic", tic, METH_NOARGS, "Start timer"},
    {"toc", toc, METH_NOARGS, "Stop timer"},
    {"res", res, METH_NOARGS, "Test timer resolution"},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
inittictoc(void) {
    Py_InitModule("tictoc", methods);
}

这适用于MacOSX,我省略了代码来检查lvl是否超出界限。虽然tictoc.res()在我的系统上产生大约50纳秒的分辨率,但我发现测量任何Python语句的抖动很容易在微秒范围内(当从IPython使用时更多)。此时,Python实现的开销变得可以忽略不计,因此可以像C实现一样使用它。

我发现tic-toc方法的实用性实际上仅限于执行时间超过10微秒的代码块。在此之下,需要像timeit这样的平均策略来获得忠实的测量。

另一答案

以防有人感兴趣。基于所有其他答案,我写了一个tictoc类,其中最好的一切。

github上的链接是here.

你也可以使用pip来获取它。

pip install ttictoc

至于如何使用它:

导入它

from ttictoc import TicToc

使用'with'语句

无需创建任何对象,您可以按照以下步骤计算代码。

with TicToc('name'):
  some code...

# Prints the elaps

以上是关于什么是Matlab的tic和toc函数的Python等价物?的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB tic-toc以Minutes格式生成

是否可以像在 Matlab 中一样在 Julia 中嵌套 tic() 和 toc() ?如果不是,那么解决方法是啥?

Matlab中tic和toc用法

tic和toc是啥函数?

在 R 中存储 tic toc 值

MATLAB中计算函数运行时间的方法