IT

Matlab의 tic 및 toc 함수에 해당하는 Python은 무엇입니까?

lottoking 2020. 9. 13. 10:53
반응형

Matlab의 tic 및 toc 함수에 해당하는 Python은 무엇입니까?


Matlab의 tic 및 toc 함수에 해당하는 Python은 무엇입니까?


timeitThiefMaster 언급 한가 을 구석으로 외에도 간단한 방법은 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생각합니다. 측정하려는 항목에 따라.


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.\n" %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.\n" %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의 가장 좋은 유사점은 용어로 정의하는 것입니다.

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설치) 아주 잘 내 프로파일 요구를 충족. 그러나 tic-toc대화식으로 구동되는 계산, 즉 GUI에서 사용자의 마우스 동작에 의해 작동되는 계산을 프로파일 링하려고 할 때도 기능에 대한 사용 사례 가 발생했습니다. 나는 소스에서 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())

이것은 스택의 시작 시간을 밀어서 작동 하므로 여러 수준의 tic의 및 tocS에 대해 올바르게 작동합니다 . 또한이 toc명령문 의 형식을 변경하여 추가 정보를 표시 할 수 있습니다. 저는 Eli의 Timer클래스 에 대해 좋아했습니다 .

어떤 GPU 순수한 구현의 오버 헤드에 관심이 있고 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 초 이상 걸리는 micro-코드 블록으로 제한 된다는 사실을 발견했습니다 . 그 아래에서는 in과 같은 평균화 전략 timeit이 충실한 측정을 위해 필요합니다.


누군가가 관심이있는 경우를 대비하여. 다른 모든 답변을 바탕으로 나는 그들 모두가 가장 좋은 tictoc 클래스를 작성했습니다.

github의 링크는 여기에 있습니다.

pip를 사용하여 얻을 수도 있습니다.

pip install ttictoc

사용 방법 :

가져 오기 오기

from ttictoc import TicToc

'with'문 사용

다음과 같이 코드 시간을 생성하지 않고 있습니다.

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

# Prints the elapsed time

또는 수행을 생성하여 동일한 작업을 수행 할 수 있습니다.

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

# Prints the elapsed time

tic toc를 명시 적으로 호출

다음과 같이 tic toc를 명시 적으로 호출 할 수도 있습니다.

t = TicToc('name')
t.tic()
some code...
t.toc()
print(t.elapsed)
With indentation

여러 수준의 코드 시간을 측정하여 '들여 쓰기'를 True로 설정하여 수행 할 수도 있습니다.

t = TicToc(,indentation=True)
t.tic()
some code1...
t.tic()
some code2...
t.tic()
some code3...
t.toc()
print('time for code 3 ',t.elapsed)
t.toc()
print('time for code 2 with code 3 ',t.elapsed)
t.toc()
print('time for code 1 with code 2 and 3 ',t.elapsed)

인수

클래스에는 이름, 방법 및 들여 쓰기의 세 가지 인수가 있습니다.

  • 이름 : 개체의 이름입니다. 필요하지 않습니다.
  • 방법 : 시간을 얻는 방법을 나타냅니다.
  • 들여 쓰기 : 동일한 개체를 시간에 따라 다른 들여 쓰기로 여러 번 사용할 수 있습니다.

메소드 인수는 int, str 또는 사용자가 선택한 메소드 일 수 있습니다. 유효한 경우 유효한 값은 time, perf_counter 및 process_time입니다. 정수인 경우 유효한 값은 0, 1, 2입니다.

  • 시간 또는 0 : time.time
  • perf_counter 또는 1 : time.perf_counter
  • process_time 또는 2 : time.process_time

Python 버전> = 3.7 인 경우 : -time_ns 또는 3 : time.time_ns-perf_counter_ns 또는 4 : time.perf_counter_ns-process_time_ns 또는 5 : time.process_time_ns

다른 방법을 선호하는 경우 (예제 time.clock 사용 :

TicToc(method=time.clock) 

수업은 다음과 가변합니다.

import sys
import time

class TicToc(object):
  """
  Counts the elapsed time.
  """
  def __init__(self,name='',method='time',indentation=False):
    """
    Args:
    name (str): Just informative, not needed
    method (int|str|ftn|clss): Still trying to understand the default
        options. 'time' uses the 'real wold' clock, while the other
        two use the cpu clock. If you want to use your own method, do it
        through this argument

        Valid int values:
          0: time.time  |  1: time.perf_counter  |  2: time.proces_time

          if python version >= 3.7:
          3: time.time_ns  |  4: time.perf_counter_ns  |  5: time.proces_time_ns

        Valid str values:
          'time': time.time  |  'perf_counter': time.perf_counter
          'process_time': time.proces_time

          if python version >= 3.7:
          'time_ns': time.time_ns  |  'perf_counter_ns': time.perf_counter_ns  
          'proces_time_ns': time.proces_time_ns

        Others:
          Whatever you want to use as time.time
    indentation (bool): Allows to do tic toc with indentation with a single object.
        If True, you can put several tics using the same object, and each toc will 
        correspond to the respective tic.
        If False, it will only register one single tic, and return the respective 
        elapsed time of the future tocs.
    """
    self.name = name
    self.indentation = indentation
    if self.indentation:
      self.tstart = []

    self.__measure = 's' # seconds

    self.__vsys = sys.version_info

    if self.__vsys[0]>2 and self.__vsys[1]>=7:
      # If python version is greater or equal than 3.7
      if type(method) is int:
        if method==0: method = 'time'
        elif method==1: method = 'perf_counter'
        elif method==2: method = 'process_time'
        elif method==3: method = 'time_ns'
        elif method==3: method = 'perf_counter_ns'
        elif method==4: method = 'process_time_ns'
        else: 
          import warnings
          msg = "Value '{0}' is not a valid option. Using 'time' instead.".format(method)
          warnings.warn(msg,Warning)
          method = 'time'

      if type(method) is str:
        if method=='time': self.get_time = time.time
        elif method=='perf_counter': self.get_time = time.perf_counter
        elif method=='process_time': self.get_time = time.process_time
        elif method=='time_ns': self.get_time = time.time_ns, self.__measure = 'ns' # nanoseconds
        elif method=='perf_counter_ns': self.get_time = time.perf_counter_ns, self.__measure = 'ns' # nanoseconds
        elif method=='process_time_ns': self.get_time = time.process_time_ns, self.__measure = 'ns' # nanoseconds
        else: 
          import warnings
          msg = "Value '{0}' is not a valid option. Using 'time' instead.".format(method)
          warnings.warn(msg,Warning)
          self.get_time = time.time

      else:
        self.get_time = method
    else:
      # If python vesion is lower than 3.7
      if type(method) is int:
        if method==0: method = 'time'
        elif method==1: method = 'perf_counter'
        elif method==2: method = 'process_time'
        else: 
          import warnings
          msg = "Value '{0}' is not a valid option. Using 'time' instead.".format(method)
          warnings.warn(msg,Warning)
          method = 'time'

      if type(method) is str:
        if method=='time': self.get_time = time.time
        elif method=='perf_counter': self.get_time = time.perf_counter
        elif method=='process_time': self.get_time = time.process_time
        else: 
          import warnings
          msg = "Value '{0}' is not a valid option. Using 'time' instead.".format(method)
          warnings.warn(msg,Warning)
          self.get_time = time.time

      else:
        self.get_time = method

  def __enter__(self):
    if self.indentation:
      self.tstart.append(self.get_time())
    else:
      self.tstart = self.get_time()

  def __exit__(self,type,value,traceback):
    self.tend = self.get_time()
    if self.indentation:
      self.elapsed = self.tend - self.tstart.pop()
    else:
      self.elapsed = self.tend - self.tstart

    if self.name!='': name = '[{}] '.format(self.name)
    else: name = self.name

    print('{0}Elapsed time: {1} ({2})'.format(name,self.elapsed,self.__measure))

  def tic(self):
    if self.indentation:
      self.tstart.append(self.get_time())
    else:
      self.tstart = self.get_time()

  def toc(self):
    self.tend = self.get_time()
    if self.indentation:
      if len(self.tstart)>0:
        self.elapsed = self.tend - self.tstart.pop()
      else:
        self.elapsed = None
    else:
      self.elapsed = self.tend - self.tstart

Matlab 이하는 일인 중첩 된 tic tocs를 달성하기 위해 모듈 [tictoc.py]을 만들었습니다.

from time import time

tics = []

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

def toc():
    if len(tics)==0:
        return None
    else:
        return time()-tics.pop()

그리고 다음과 같이 작동합니다.

from tictoc import tic, toc

# This keeps track of the whole process
tic()

# Timing a small portion of code (maybe a loop)
tic()

# -- Nested code here --

# End
toc()  # This returns the elapse time (in seconds) since the last invocation of tic()
toc()  # This does the same for the first tic()

도움이되기를 바랍니다.


timeit을 모듈 살펴보십시오 . 사용은 동일하지만 사용할 수 있습니다.


이는 래퍼를 사용하여 수행 할 수도 있습니다. 시간을 유지하는 매우 일반적인 방법.

이 예제 코드의 래퍼는 함수를 래핑하고 함수를 실행하는 데 필요한 시간을 인쇄합니다.

def timethis(f):
    import time

    def wrapped(*args, **kwargs):
        start = time.time()
        r = f(*args, **kwargs)
        print "Executing {0} took {1} seconds".format(f.func_name,  time.time()-start)
        return r
    return wrapped

@timethis
def thistakestime():
    for x in range(10000000):
        pass

thistakestime()

@Eli Bendersky의 대답을 약간 변경하여 ctor __init__()와 dtor 를 사용 __del__()하여 타이밍을 수행하여 원래 코드를 들여 쓰지 더 편리하게 사용할 수 있습니다.

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

    def __del__(self):
        if self.name:
            print '%s elapsed: %.2fs' % (self.name, time.time() - self.tstart)
        else:
            print 'Elapsed: %.2fs' % (time.time() - self.tstart)

사용중인 일부 로컬 범위의 시작 부분에 Timer ( "blahblah")를 포함합니다. 경과 시간은 범위 끝까지 인쇄됩니다.

for i in xrange(5):
    timer = Timer("eigh()")
    x = numpy.random.random((4000,4000));
    x = (x+x.T)/2
    numpy.linalg.eigh(x)
    print i+1
timer = None

다음과 같이 출력됩니다.

1
eigh() elapsed: 10.13s
2
eigh() elapsed: 9.74s
3
eigh() elapsed: 10.70s
4
eigh() elapsed: 10.25s
5
eigh() elapsed: 11.28s

파이썬 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

또한보고 된 시간 단위 (초)를 인쇄하고 제안한대로 자릿수를 자르고 로그 파일에 추가하는 옵션을 사용하여 업데이트했습니다. 로깅 기능을 사용하는 경우 날짜 시간을 가져와야합니다.

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

A의 utils.py모듈 및 나는 함께 사용

from utils import Tictoc
tic, toc = Tictoc()

이 방법

  • 당신은 간단하게 사용할 수 있습니다 tic(), toc()둥지 그들 매트랩 좋아
  • 양자 택일로, 당신은 그 이름을 수 있습니다 tic(1), toc(1)또는 tic('very-important-block'), toc('very-important-block')다른 이름을 가진 타이머는 방해하지 않을 것이다
  • 이런 식으로 가져 오기 오면 사용하는 모듈을 막을 수 있습니다.

(여기서 toc는 경과 시간을 인쇄하지 않고 반환합니다.)

참고 URL : https://stackoverflow.com/questions/5849800/what-is-the-python-equivalent-of-matlabs-tic-and-toc-functions

반응형