精华内容
下载资源
问答
  • Python 计算函数运行时间

    万次阅读 2019-03-26 11:27:31
    那么本文推荐两种监控函数运行时间的方法。 方法一: 在程序内使用time模块记录时间,计算使用的时间 import time def test(): start_time = time.time() # 记录程序开始运行时间 s = 0 for i in r...

    在Python中,有时候为了优化代码,我们需要监控哪些函数使用了比较多的时间,或者是为了单纯查看函数的运行时间。那么本文推荐两种监控函数运行时间的方法。


    方法一: 在程序内使用time模块记录时间,计算使用的时间
    import time
    
    def test():
        start_time = time.time()  # 记录程序开始运行时间
        s = 0
        for i in range(1000000):
            s += 1
        end_time = time.time()  # 记录程序结束运行时间
        print('Took %f second' % (end_time - start_time))
        return s
    
    test()
    
    # 运行结果:
    Took 0.085060 second
    Out[47]: 1000000
    

    这种方法快速简单,只需要在程序中加入三行命令即可实现运行时间的计算。


    方法二:定义装饰器,装饰需要计算时间的函数进行监控
    import time
    from functools import wraps
    
    def timefn(fn):
        """计算性能的修饰器"""
        @wraps(fn)
        def measure_time(*args, **kwargs):
            t1 = time.time()
            result = fn(*args, **kwargs)
            t2 = time.time()
            print(f"@timefn: {fn.__name__} took {t2 - t1: .5f} s")
            return result
        return measure_time
    
    
    # 在定义函数前进行装饰
    @timefn
    def test():
        s = 0
        for i in range(1000000):
            s += 1
        return s
        
    test()
    
    # 运行结果:
    @timefn: test took 0.05930 s
    Out[15]: 1000000
    

    这种方法显然更具有复用性,同时也更Pythonic。适合在程序中有多个函数需要监控时间的时候使用。需要注意的是:在Python2中获取函数名称的写法为fn.func_name,而在Python3中变为了fn.__name__。该用法涉及到装饰器的使用,想要更深入地了解可以到:
    http://www.runoob.com/w3cnote/python-func-decorators.html
    上面的这种写法也相当于:

    timefn(test())
    # 运行结果:
    @timefn: test took 0.05956 s
    Out[16]: <function __main__.timefn.<locals>.measure_time>
    

    但装饰器的写法不会破坏原来函数的结构。

    展开全文
  • Python装饰器(计算函数运行花费时间) – ​ 已经存在两个功能相同的函数,这个函数是对m3u8文件进行解析,提取其中的ts视频片段链接: 文件部分内容( 本文解析的m3u8文件附件): #EXTM3U #EXT-X-...

    Python装饰器(计算函数运行花费时间)

        python的装饰器和java的面向切面变成很相似,面向切面编程主要关心的是函数运行前(Before)和函数运行结束(After),可以针对函数前后做功能修复、功能插入工作,比如一些通用的打印日志,计算函数运行时间,拦截函数做一些事前处理, 相比而言python的装饰器更加灵活好用。

    1. 现在想要比较两个功能相同函数的性能,计算函数的运行时间

      def parse_m3u8_file(m3u8_uri)pass
      	# Before: 运行开始时间
          # Running: 函数体运行中
          # After:   运行结束时间
          # 计算函数运行时间差并输出
      

          完成这个功能,需要改写每个函数的函数体,并向上述描述添加重复代码,冗余而又乏味;有没有一种操作可以不用触及函数体的改动(或者微小改动)?装饰器可以优雅的完成这一功能。

      import time
      
      def timefn1(fn):
          '''
          :param fn: 被装饰器修饰的函数,将作为装饰器的默认参数传入
          :return: 被装饰的函数本身 
          '''
          def measure_use_time(*args, **kw):
              '''
              函数传参方式 fn(arg1, arg2, param1=a, param2=b)
              :param args: 位置参数(arg1, arg2, ....)  传参方式 fn(arg1, arg2, ...)
              :param kw: 字典参数{param1=a, param2=b, .....} 传参方式 fn(param1=a, param2=b, ....)
              :return: 
              '''
              t1 = time.time()
              res = fn(*args, **kw)
              t2 = time.time()
              print("@timefn: %s took %s" % (fn.__name__, t2-t1)
              return res
          return measure_use_time
      
      # 函数的定义上加@timefn1即可输出函数运行时间
      '''
      	形如:
      	@timefn1
      	def parse_m3u8_file(m3u8_uri):
      		pass
      '''
              
      
    2. 功能函数介绍:这个函数是对m3u8文件进行解析,提取其中的ts视频片段链接:

      文件部分内容( 本文解析的m3u8文件附件):

      #EXTM3U
      #EXT-X-VERSION:3
      #EXT-X-TARGETDURATION:6
      #EXT-X-PLAYLIST-TYPE:VOD
      #EXT-X-MEDIA-SEQUENCE:0
      #EXT-X-KEY:METHOD=AES-128,URI="https://ts1.yuyuangewh.com:9999/20201006/a15C23PF/1000kb/hls/key.key"
      #EXTINF:4.28,
      https://ts1.yuyuangewh.com:9999/20201006/a15C23PF/1000kb/hls/nKw4m62o.ts
      #EXTINF:1.96,
      https://ts1.yuyuangewh.com:9999/20201006/a15C23PF/1000kb/hls/LFoLf2u7.ts
      #EXTINF:3.12,
      https://ts1.yuyuangewh.com:9999/20201006/a15C23PF/1000kb/hls/qhKKazou.ts
      #EXT-X-ENDLIST
      

      函数代码部分:

      def parse_m3u8_file(m3u8_uri):
          '''
          解析m3u8格式文件,得到ts视频片段链接
              全部读取文件内容,进行正则匹配(ts链接URL)
          :param m3u8_uri: 本地缓存的m3u8文件路径
          :return: 
          '''
          with open(m3u8_uri, 'r') as fr:
              data = fr.read()
              ts_pattern = r"https://.*\.ts"
              ts_urls = re.findall(ts_pattern, data)
          return ts_urls
      
      def parse_m3u8(m3u8_uri):
          '''
          解析m3u8格式文件,得到ts视频片段链接
              逐行读取文件内容,添加ts链接URL(不以#开头)
          :param m3u8_uri: 本地缓存的m3u8文件路径
          :return: 
          '''
          ts_urls = []
          fr = open(m3u8_uri, 'r')
          while True:
              buf = fr.readline()
              if not buf:
                  print(m3u8_uri + ' has read...')
                  break
              if not buf.startswith('#'):
                  ts_urls.append(buf.strip())
          fr.close()
          return ts_urls
      
    3. 装饰器改进:
      ​     如果你现在想给装饰器提供参数来简要说明一下函数的用法(或者其他用途的参数),这个fn(被装饰器修饰的函数)不是不能作为默认参数传入了?python提供了解决方案(funtools.wrap来装饰函数):

      from functools import wraps
      import logging
      
      def timefn2(fn_use=''):
          '''
          :param fn_use: 装饰器的参数 
          '''
          def wrapper(fn):
              @wraps(fn)			#lookat here
              def measure_use_time(*args, **kw):
                  '''
                  函数传参方式 fn(arg1, arg2, param1=a, param2=b)
                  :param args: 位置参数(arg1, arg2, ....)  传参方式 fn(arg1, arg2, ...)
                  :param kw: 字典参数{param1=a, param2=b, .....} 传参方式 fn(param1=a, param2=b, ....)
                  :return:
                  '''
                  t1 = time.time()
                  res = fn(*args, **kw)
                  t2 = time.time()
                  logging.warning("@timefn: %s(%s) took %s" % (fn.__name__, fn_use, format_use_time(t2 - t1)))
                  return res
              return measure_use_time
          return wrapper
      
      # 性能计算功能的添加需要加入装饰器@timefn2
      '''
      	形如:
      	# 不带函数用途的写法
      	@timefn2()
      	def parse_m3u8_file(m3u8_uri):
      		pass
      	
      	# 带函数用途的写法
      	@timefn2('parse2')
      	def parse_m3u8(m3u8_uri):
      		pass
      '''
      

      ​     注意到上面使用到了一个函数format_use_time是将秒数转化成时分秒的格式,方便查看; 第二个引入了日志模块,不在使用print来进行控制台输出:

      def format_use_time(seconds):
          '''
             将秒数转化为 HH:MM:SS格式
             :param seconds: 
             :return: 格式化字符串
          '''
          
          """
              # 其他语言通用写法
              h = int(seconds/3600)
              seconds_ = seconds % 3600
              m = int(seconds_/60)
              s = seconds_ % 60
              return "{:0>2d}:{:0>2d}:{:0>9.6f}".format(h, m, s)
          """
      
          m, s = divmod(seconds, 60)
          h, m = divmod(m, 60)
          return "{:0>2d}:{:0>2d}:{:0>9.6f}".format(int(h), int(m), s)
      

      ​     优化上面的装饰器函数,加入异常处理机制:

      from functools import wraps
      import logging
      
      def timefn(fn_use=''):
          '''
          :param fn_use: 装饰器的参数
          '''
          def wrapper(fn):
              @wraps(fn)
              def measure_use_time(*args, **kw):
                  '''
                  函数传参方式 fn(arg1, arg2, param1=a, param2=b)
                  :param args: 位置参数(arg1, arg2, ....)  传参方式 fn(arg1, arg2, ...)
                  :param kw: 字典参数{param1=a, param2=b, .....} 传参方式 fn(param1=a, param2=b, ....)
                  :return:
                  '''
                  t1 = time.time()
                  try:
                      res = fn(*args, **kw)
                  except Exception as e:
                      logging.error(f"@timefn %s(%s) execute error" % (fn.__name__, fn_use))
                      # decide whether throw exception or not (决定受否抛出异常,终止程序)
                      # raise e
                      return None
                  else:
                      t2 = time.time()
                      logging.warning("@timefn: %s(%s) took %s" % (fn.__name__, fn_use, format_use_time(t2 - t1)))
                      return res
              return measure_use_time
          return wrapper
      
    展开全文
  • 利用timeit库。 import timeit def add(x, y): print(x + y) ...print(timeit.timeit(lambda: add(1, 2), number=1)) # 必须使用匿名函数的形式,number指定函数运行次数 输出: 3 2.1199999999998997e-05

    利用timeit库。

    import timeit
    
    
    def add(x, y):
        print(x + y)
    
    
    print(timeit.timeit(lambda: add(1, 2), number=1))  # 必须使用匿名函数的形式,number指定函数运行次数
    

    输出:

    3
    2.1199999999998997e-05
    
    展开全文
  • Python计算函数运行时间

    千次阅读 2017-07-18 16:34:54
    >>> def timeFun(): ...... time_start = time.time() #time.time()为1970.1.1到当前时间的毫秒数 ... b, alphas = svmMLiA.smoSimple(dataArr, labelArr, 0.6, 0.001, 40) # 运行主体 ... time_en
    >>> def timeFun():
    ...     import time
    ...     time_start = time.time()  #time.time()为1970.1.1到当前时间的毫秒数 
    ...     b, alphas = svmMLiA.smoSimple(dataArr, labelArr, 0.6, 0.001, 40)  # 运行主体
    ...     time_end = time.time()
    ...     print time_end - time_start
    ...     
    >>> timeFun()
    展开全文
  • 本文主要是利用python装饰器计算函数运行时间 一些需要精确的计算函数运行了多久的程序,都可以采用这种方法 #coding:utf-8 import urllib2,re,time,random,os,datetime import HTMLParser import sys reload(sys) ...
  • 定义一个计算执行时间函数作装饰器,传入参数为装饰的函数或方法 def print_execute_time(func): from time import time # 定义嵌套函数,用来打印出装饰的函数的执行时间 def wrapper(*args, **kwargs): # ...
  • 同往日的混为一谈,小编也知道基本上都可会即可算函数运行时间,这是基础中的基础,没什么好讲的,但是时间是宝贵的,最大限度的使用利用是非常重要的,因为,小编要教大家来看下怎么去快速计算函数的运行时间,这里...
  • 本文主要是利用python装饰器计算函数运行时间一些需要精确的计算函数运行了多久的程序,都可以采用这种方法#coding:utf-8import urllib2,re,time,random,os,datetimeimport HTMLParserimport...
  • 使用python装饰器计算函数运行时间

    万次阅读 2017-05-04 17:05:55
    装饰器在python里面有很重要的作用...本文主要是利用python装饰器计算函数运行时间 一些需要精确的计算函数运行了多久的程序,都可以采用这种方法 #coding:utf-8 import urllib2,re,time,random,os,datetime imp

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 528
精华内容 211
关键字:

python计算函数运行时间

python 订阅