zoukankan      html  css  js  c++  java
  • 计算运行时间工具timeit

    timeit的功能和用法

    timeit 模块提供了测试一小段代码运行时间的功能。我前面有一篇文章用它来测试定义 __slots__ 对对象访问速度的提升情况,参见这里
    官方文档 上有下面这样的使用例子:

    # 从命令行调用
    python -m timeit '"-".join([str(n) for n in range(100)])'
    
    # 从REPL调用
    >>> import timeit
    >>> timeit.timeit('"-".join([str(n) for n in range(100)])', number=10000)
    0.7288308143615723
    

    使用 timeit 的时候可以直接调用其定义好的 timeit.timeit , timeit.repeat , timeit.default_timer 方法,或者定义一个类 timeit.Timer ,使用本身的方法。

    # API
    
    timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000)
    
    timeit.repeat(stmt='pass', setup='pass', timer=<default timer>, repeat=3, number=1000000)
    
    class timeit.Timer(stmt='pass', setup='pass', timer=<timer function>)¶
    
    • timeit() 接受的第一个参数stmt为要计算时间的表达式,第二个参数setup为初始化的表达式。
    • timer参数为计时器,在不同平台默认不一样,参照这里 ,但不管是Unix还是Windows测得的时间都是系统经过的时间,所以是有可能被正在运行的其它程序影响的。
    • number参数是表达式执行的次数,所以这里返回的时间是执行1000000次总和的时间。
    • timeit.repeat() 中的repeat参数是测试重复执行的次数,相当于调用number次的timeit(),number默认为3,返回3次运行时间的列表,通常可以取min()来评估程序的执行时间。
    • timeit.repeat() 中除了最小值其他的值得参考意义可能不大,因为有可能是受到系统中其它程序影响导致的
    • 注意python版本不同导致的接口参数不同,这里默认采用python2.7版本

    接下来看一些复杂点的示例

    # 多行表达式的调用
    >>> import timeit
    >>> attribute is missing
    >>> s = """
    ... try:
    ...     str.__nonzero__
    ... except AttributeError:
    ...     pass
    ... """
    >>> timeit.timeit(stmt=s, number=100000)
    0.9138244460009446
    
    
    # 测试函数调用时间
    def test():
        """Stupid test function"""
        L = []
        for i in range(100):
            L.append(i)
    
    if __name__ == '__main__':
        import timeit
        print(timeit.timeit("test()", setup="from __main__ import test"))
    

    其它

    当我在网上浏览timeit相关资源时看到了这篇文章, 上面提到了通过上下文管理器(context manager)实现一个计时器,利用了变量的生命周期相关特性(#TODO),虽然就像作者所说,可以加上其它的特性比如循环次数等以及更优雅的实现一个计时器,代码如下,可供参考:

    # Source code: https://gist.github.com/pengmeng/78a25663c20ab8890b81
    __author__ = 'mengpeng'
    import time
    
    
    class timeme(object):
        __unitfactor = {'s': 1,
                        'ms': 1000,
                        'us': 1000000}
    
        def __init__(self, unit='s', precision=4):
            self.start = None
            self.end = None
            self.total = 0
            self.unit = unit
            self.precision = precision
    
        def __enter__(self):
            if self.unit not in timeme.__unitfactor:
                raise KeyError('Unsupported time unit.')
            self.start = time.time()
            return self
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            self.end = time.time()
            self.total = (self.end - self.start) * timeme.__unitfactor[self.unit]
            self.total = round(self.total, self.precision)
    
        def __str__(self):
            return 'Running time is {0}{1}'.format(self.total, self.unit)
    

    运行示例:

    from timeme import timeme
    with timeme('ms', 6) as t:
        result = sum(range(100000))
    
    print(t) # Running time is 5.2948ms
    print(t.total) # 5.2948
    

    参考资料

  • 相关阅读:
    乐动力APP案例
    四则运算题目自动生成
    第0次作业
    CMDB整体项目梳理(1)
    cmdb项目准备
    DjangoAgain CBV与FBV
    Django ORM不完全操作
    Django 查漏补缺记录
    DjangoAgain_用小程序理解web框架
    DjangoAgain_url路由系统
  • 原文地址:https://www.cnblogs.com/nisen/p/6045182.html
Copyright © 2011-2022 走看看