Ale*_*lex 90 python matlab timing
Python 中MATLAB tic和toc函数(http://www.mathworks.com/help/techdoc/ref/tic.html)的最佳模拟是什么?
Eli*_*sky 143
除了timeit
ThiefMaster提到的,一个简单的方法就是(导入后time
):
t = time.time()
# do stuff
elapsed = time.time() - t
Run Code Online (Sandbox Code Playgroud)
我有一个我喜欢使用的辅助类:
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))
Run Code Online (Sandbox Code Playgroud)
它可以用作上下文管理器:
with Timer('foo_stuff'):
# do some foo
# do some stuff
Run Code Online (Sandbox Code Playgroud)
有时候我发现这种技术比timeit
- 这更取决于你想要测量的东西.
小智 25
当我从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)
Run Code Online (Sandbox Code Playgroud)
而已!现在我们已经准备好充分利用tic()
,toc()
就像在Matlab中一样.例如
tic()
time.sleep(5)
toc() # returns "Elapsed time: 5.00 seconds."
Run Code Online (Sandbox Code Playgroud)
实际上,这比内置的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)
Run Code Online (Sandbox Code Playgroud)
现在,您应该能够计算两个不同的东西:在下面的示例中,我们分别计算脚本的总脚本和部分时间.
tic()
time.sleep(5)
tic2()
time.sleep(3)
toc2() # returns "Elapsed time 2: 5.00 seconds."
toc() # returns "Elapsed time: 8.00 seconds."
Run Code Online (Sandbox Code Playgroud)
实际上,您甚至不需要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...
Run Code Online (Sandbox Code Playgroud)
我希望这有用.
小智 19
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"
Run Code Online (Sandbox Code Playgroud)
然后你可以使用它们:
tic()
# do stuff
toc()
Run Code Online (Sandbox Code Playgroud)
Ste*_*fan 11
通常情况下,IPython中的%time
,%timeit
,%prun
和%lprun
(如果已line_profiler
安装)满足我的需求分析得不错.但是,tic-toc
当我尝试剖析交互式驱动的计算时,即用户在GUI中的鼠标移动时,会出现类似功能的用例.我觉得在源代码中发送垃圾信息tic
,toc
而交互式测试则是揭示瓶颈的最快方法.我选择了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())
Run Code Online (Sandbox Code Playgroud)
由于这可以通过在堆栈上按下开始时间来工作,因此它将适用于多个级别的tic
s和toc
s.它还允许人们更改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);
}
Run Code Online (Sandbox Code Playgroud)
这是针对MacOSX的,lvl
为了简洁起见,我省略了代码以检查是否超出范围.虽然tictoc.res()
在我的系统上产生了大约50纳秒的分辨率,但我发现测量任何Python语句的抖动很容易在微秒范围内(当从IPython使用时更多).此时,Python实现的开销变得可以忽略不计,因此可以与C实现一样使用它.
我发现tic-toc
-approach的实用性实际上仅限于执行时间超过10微秒的代码块.在此之下,需要采用平均策略timeit
来获得忠实的测量.
以防万一有人感兴趣。基于所有其他答案,我编写了一个tictoc类,该类具有全部优点。
github上的链接在这里。
您也可以使用点子获取它。
pip install ttictoc
Run Code Online (Sandbox Code Playgroud)
关于如何使用它:
from ttictoc import TicToc
Run Code Online (Sandbox Code Playgroud)
无需创建任何对象,您就可以按以下方式对代码进行计时。
with TicToc('name'):
some code...
# Prints the elapsed time
Run Code Online (Sandbox Code Playgroud)
或者通过创建对象,您可以执行相同的操作。
t = TicToc('name')
with t:
some code...
# Prints the elapsed time
Run Code Online (Sandbox Code Playgroud)
您还可以如下所示显式调用tic toc。
t = TicToc('name')
t.tic()
some code...
t.toc()
print(t.elapsed)
With indentation
Run Code Online (Sandbox Code Playgroud)
如果您想对代码的多个级别进行计时,也可以通过将'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)
Run Code Online (Sandbox Code Playgroud)
该类具有3个参数:name,method和indentation。
方法参数可以是int,str或您的方法选择。如果是字符串,则有效值为time,perf_counter和process_time。如果是整数,则有效值为0、1和2。
如果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)
Run Code Online (Sandbox Code Playgroud)
该类如下:
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
Run Code Online (Sandbox Code Playgroud)
小智 6
我刚刚创建了一个模块[tictoc.py]来实现嵌套的tic tocs,这就是Matlab所做的.
from time import time
tics = []
def tic():
tics.append(time())
def toc():
if len(tics)==0:
return None
else:
return time()-tics.pop()
Run Code Online (Sandbox Code Playgroud)
它的工作原理如下:
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()
Run Code Online (Sandbox Code Playgroud)
我希望它有所帮助.
小智 5
pip install easy-tictoc
Run Code Online (Sandbox Code Playgroud)
在代码中:
from tictoc import tic, toc
tic()
#Some code
toc()
Run Code Online (Sandbox Code Playgroud)
免责声明:我是这个库的作者。
归档时间: |
|
查看次数: |
108630 次 |
最近记录: |