最新消息:博主的视频课程:Django高级实战教程 开发企业级问答网站开发

Python中少量代码运行计时

Python liaogx 来源:西部世界 925浏览 0评论

一、使用time模块获得起始和终止时间然后相减获得运行时间,Python中最原始的设计方案

import time
start = time.time()
# code to run
end = time.time()
cost = end - start #time in second

二、计时模块timeit,该模块提供了较为完善的计时功能,而且支持重复测试

def test1():
    n=0
    for i in range(101):
        n+=i
    return n

def test2():
    return sum(range(101))

def test3():
    return sum(x for x in range(101))

if __name__=='__main__':
    from timeit import Timer
    t1=Timer("test1()","from __main__ import test1")
    t2=Timer("test2()","from __main__ import test2")
    t3=Timer("test3()","from __main__ import test3")
    print (t1.timeit(1000000))
    print (t2.timeit(1000000))
    print (t3.timeit(1000000))
    print (t1.repeat(3,1000000))
    print (t2.repeat(3,1000000))
    print (t3.repeat(3,1000000))

以上是两种较为常见的计时功能,有相应的优缺点:

  • 第一种方案较为直观,需要了解time模块的使用方法,并且需要进行单位转换
  • 第二种方案有官方支持,但是不方便用于测量非函数代码块(例如某几行代码的运行时间),而且需要通过参数来配置测试环境

三、使用自定义的上下文管理器(Context Manager)

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)

在一些简单的计时任务中,相比于使用timeit模块更加灵活而且无需手动配置运行环境;相比于使用手动计时减少了代码行数。

方法二与方法三对比:

import time
from timeit import Timer

def test1():
    n = 0
    for i in range(1001):
        n += 1
    return n

def test2():
    return sum(range(1001))

def test3():
    return sum(x for x in range(1001))

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 '{0}{1}'.format(self.total, self.unit)

if __name__ == '__main__':

    t1 = Timer("test1()", "from __main__ import test1")
    t2 = Timer("test2()", "from __main__ import test2")
    t3 = Timer("test3()", "from __main__ import test3")

    timeit_time = t1.timeit(10000)
    with Timeme('s', 6) as with_time:
        t1.timeit(10000)
    print(timeit_time, ' <- -> ', with_time)  #对比利用timeit模块和上下文管理器的时间,一下同理

    timeit_time = t2.timeit(10000)
    with Timeme('s', 6) as with_time:
        t2.timeit(10000)
    print(timeit_time, ' <- -> ', with_time)

    timeit_time = t3.timeit(10000)
    with Timeme('s', 6) as with_time:
        t3.timeit(10000)
    print(timeit_time, ' <- -> ', with_time)

    print('timeit_time:', t1.repeat(3, 10000))
    with Timeme('s', 6) as with_time:
        print('with_time:', t1.repeat(3, 10000))

    print('timeit_time:', t2.repeat(3, 10000))
    with Timeme('s', 6) as with_time:
        print('with_time:', t2.repeat(3, 10000))

    print('timeit_time:', t3.repeat(3, 10000))
    with Timeme('s', 6) as with_time:
        print('with_time:', t3.repeat(3, 10000))

运行结果:

0.43699180091662354 <- -> 0.438308s
0.16189893455339266 <- -> 0.155123s
0.5677286920547449 <- -> 0.569402s
timeit_time: [0.43541396094283513, 0.4349051203808605, 0.43526276937166664]
with_time: [0.43700166981813604, 0.43875912379944815, 0.43557265287915303]
timeit_time: [0.15618089301715976, 0.15521295115683298, 0.15627918727622347]
with_time: [0.15499149300689563, 0.1587029894876455, 0.15474477046908852]
timeit_time: [0.564173913730011, 0.5690219129089176, 0.5746610032330519]
with_time: [0.5675455252426769, 0.5730263183865532, 0.5699436683101666]

转载请注明:西部世界 » Python中少量代码运行计时

发表我的评论
取消评论

表情