• 计算运行时间工具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
    

    参考资料

  • 相关阅读:
    bootstrap的portlet组件框框的应用 (点击可伸缩)
    jQuery.trim() 函数及trim()用法详解
    针对谷歌浏览器Chrome的CSS hack
    CSS-如何禁用a标签
    textarea中文本前总是空2格,写入数据库也是
    JNI编程实现(Windows)
    JNI编程实现(Linux)
    FastDFS安装步骤
    iOS离屏渲染之优化分析
    Nginx入门案例(Mac版)
  • 原文地址:https://www.cnblogs.com/nisen/p/6045182.html
Copyright © 2020-2023  润新知