当前位置: 首页 > news >正文

python函数装饰器参数统计调用时间和次数

1 python函数装饰器参数统计调用时间和次数

python在函数装饰器外层定义一个函数生成封闭作用域来保存装饰器入参,供装饰器使用。

1.1 装饰器统计调用时间和次数

描述

通过类的可调用实例装饰器来统计函数每次调用时间和总调用时间,以及调用次数。

(1) time.perf_counter()获取当前时间,单位秒;

(2) 调用函数func前和后的时间差,为func的执行时间usetime;

(3) 将每次的执行时间usetime累加,获得总时间alltime;

(4) 每调用一次func,calls计增一次获得总次数;

(5) 比较列表解析和map内置函数生成列表的调用时间;

(6) map在py2返回列表,在py3返回迭代器,需用list转为列表;

示例

>>> import time,sys
>>> class TimeCount:def __init__(self,func):self.func=funcself.alltime=0self.calls=0def __call__(self,*args,**kargs):begin=time.perf_counter()res=self.func(*args,**kargs)usetime=time.perf_counter()-beginself.alltime+=usetimeself.calls+=1callstr=' 调用 {0[0]} {0[1]} 次 'calltpl=self.func.__name__,self.callstimestr='{0[0]}:usetime={0[1]:.6f},alltime={0[2]:.6f}'timetpl=self.func.__name__,usetime,self.alltimeresstr='res[0]={0[0]},res[-1]={0[1]},len(res)={0[2]}'restpl=res[0],res[-1],len(res)print(callstr.format(calltpl).center(50,'-'))print(timestr.format(timetpl))print(resstr.format(restpl),'\n')>>> @TimeCount
def listcomp(N):return [x*2 for x in range(N)]>>> if sys.version_info[0]==2:@TimeCountdef mapcall(N):return map((lambda x:x*2),range(N))
else:@TimeCountdef mapcall(N):# py3的map返回迭代器需用list转换# 否则统计的时间与listcomp不一致return list(map((lambda x:x*2),range(N)))>>> xtpl=5,50000,500000,1000000
>>> tuple(map(listcomp,xtpl))
---------------- 调用 listcomp 1-----------------
listcomp:usetime=0.000005,alltime=0.000005
res[0]=0,res[-1]=8,len(res)=5 ---------------- 调用 listcomp 2-----------------
listcomp:usetime=0.002395,alltime=0.002400
res[0]=0,res[-1]=99998,len(res)=50000 ---------------- 调用 listcomp 3-----------------
listcomp:usetime=0.026660,alltime=0.029060
res[0]=0,res[-1]=999998,len(res)=500000 ---------------- 调用 listcomp 4-----------------
listcomp:usetime=0.053023,alltime=0.082084
res[0]=0,res[-1]=1999998,len(res)=1000000 (None, None, None, None)
>>> tuple(map(mapcall,xtpl))
----------------- 调用 mapcall 1-----------------
mapcall:usetime=0.000005,alltime=0.000005
res[0]=0,res[-1]=8,len(res)=5 ----------------- 调用 mapcall 2-----------------
mapcall:usetime=0.003963,alltime=0.003968
res[0]=0,res[-1]=99998,len(res)=50000 ----------------- 调用 mapcall 3-----------------
mapcall:usetime=0.041263,alltime=0.045231
res[0]=0,res[-1]=999998,len(res)=500000 ----------------- 调用 mapcall 4-----------------
mapcall:usetime=0.083637,alltime=0.128868
res[0]=0,res[-1]=1999998,len(res)=1000000 (None, None, None, None)
>>> '{:.6f}'.format(mapcall.alltime)
'0.128868'
>>> '{:.6f}'.format(listcomp.alltime)
'0.082084'
>>> '{:.6f}'.format(mapcall.alltime/listcomp.alltime)
'1.569957'

1.2 嵌套函数统计电影时间和次数

描述

通过嵌套函数来统计函数每次调用时间和总调用时间,以及调用次数。

(1) time.perf_counter()获取当前时间,单位秒;

(2) 调用函数func前和后的时间差,为func的执行时间usetime;

(3) 将每次的执行时间usetime累加,获得总时间alltime;

(4) 每调用一次func,calls计增一次获得总次数;

(5) 比较列表解析和map内置函数生成列表的调用时间;

(6) map在py2返回列表,在py3返回迭代器,需用list转为列表;

(7) 将alltime和calls赋值给func进行返回,供后续获取;

(8) 通过nonlocal修改嵌套作用域的变量alltime和calls;

示例

>>> import time,sys
>>> def timecount_func(func):alltime=0calls=0def tcf_wrapper(*pargs,**kargs):begin = time.perf_counter()res=func(*pargs,**kargs)usetime = time.perf_counter() - beginnonlocal alltimenonlocal callsalltime+=usetimecalls+=1timestr='{0[0]}:usetime={0[1]:.6f},alltime={0[2]:.6f}'timetpl=func.__name__,usetime,alltimecallstr=' 调用 {0[0]} {0[1]} 次 'calltpl=func.__name__,callsresstr='res[0]={0[0]},res[-1]={0[1]},len(res)={0[2]}'restpl=res[0],res[-1],len(res)print(callstr.format(calltpl).center(50,'-'))print(timestr.format(timetpl))print(resstr.format(restpl),'\n')func.alltime=alltimefunc.calls=callsreturn tcf_wrapper>>> def listcomp(N):return [x*2 for x in range(N)]>>> if sys.version_info[0]==2:def mapcall(N):return map((lambda x:x*2),range(N))
else:def mapcall(N):return list(map((lambda x:x*2),range(N)))>>> xtpl=5,50000,500000,1000000
>>> tuple(map(timecount_func(listcomp),xtpl))
---------------- 调用 listcomp 1-----------------
listcomp:usetime=0.000005,alltime=0.000005
res[0]=0,res[-1]=8,len(res)=5 ---------------- 调用 listcomp 2-----------------
listcomp:usetime=0.002478,alltime=0.002482
res[0]=0,res[-1]=99998,len(res)=50000 ---------------- 调用 listcomp 3-----------------
listcomp:usetime=0.031966,alltime=0.034448
res[0]=0,res[-1]=999998,len(res)=500000 ---------------- 调用 listcomp 4-----------------
listcomp:usetime=0.068800,alltime=0.103248
res[0]=0,res[-1]=1999998,len(res)=1000000 (None, None, None, None)
>>> tuple(map(timecount_func(mapcall),xtpl))
----------------- 调用 mapcall 1-----------------
mapcall:usetime=0.000006,alltime=0.000006
res[0]=0,res[-1]=8,len(res)=5 ----------------- 调用 mapcall 2-----------------
mapcall:usetime=0.004435,alltime=0.004441
res[0]=0,res[-1]=99998,len(res)=50000 ----------------- 调用 mapcall 3-----------------
mapcall:usetime=0.041257,alltime=0.045698
res[0]=0,res[-1]=999998,len(res)=500000 ----------------- 调用 mapcall 4-----------------
mapcall:usetime=0.082711,alltime=0.128409
res[0]=0,res[-1]=1999998,len(res)=1000000 (None, None, None, None)
>>> '{:.6f}'.format(mapcall.alltime)
'0.128409'
>>> '{:.6f}'.format(listcomp.alltime)
'0.103248'
>>> '{:.6f}'.format(mapcall.alltime/listcomp.alltime)
'1.243693'

1.3 函数装饰器参数

通过装饰器参数指定配置选项。在装饰的时候传入一个标签和一个跟踪控制标志。

提供一个输出标签,以及打开或关闭跟踪消息,

用法

def close_scope_func(label='',trace=True):def decorator(func):def onCall(*args):passfunc(*args)passreturn decorator@close_scope_func('梯阅线条')
def test_func(x):passtest_func('tyxt')

描述

装饰器参数需在外层添加一个函数生成一个封闭作用域用来保存参数,供装饰器使用。

(1) 在装饰器外层定义一个函数,并且指定装饰器需要的入参;

(2) 外层函数需返回一个可调用的装饰器,给到被装饰函数;

(3) 装饰函数时,传入对应入参即可;

示例

>>> import time,sys
>>> def timecount_ctr(label='',trace=True):class TimeCount:def __init__(self,func):self.func=funcself.alltime=0self.calls=0def __call__(self,*args,**kargs):begin=time.perf_counter()res=self.func(*args,**kargs)usetime=time.perf_counter()-beginself.alltime+=usetimeself.calls+=1if trace:callstr=' 调用 {0[0]} {0[1]} 次 'callval=self.func.__name__,self.callstimestr='{0[0]}:usetime={0[1]:.6f},alltime={0[2]:.6f}'timeval=self.func.__name__,usetime,self.alltimeresstr='res[0]={0[0]},res[-1]={0[1]},len(res)={0[2]}'resval=res[0],res[-1],len(res)print(label,callstr.format(callval).center(50,'-'))print(label,timestr.format(timeval))print(label,resstr.format(resval),'\n')return TimeCount>>> @timecount_ctr('[listcomp]==>')
def listcomp(N):return [x*2 for x in range(N)]>>> if sys.version_info[0]==2:@timecount_ctr('[mapcall]==>')def mapcall(N):return map((lambda x:x*2),range(N))
else:@timecount_ctr('[mapcall]==>')def mapcall(N):# py3的map返回迭代器需用list转换# 否则统计的时间与listcomp不一致return list(map((lambda x:x*2),range(N)))>>> xtpl=5,50000,500000,1000000
>>> tuple(map(listcomp,xtpl))
[listcomp]==> ---------------- 调用 listcomp 1-----------------
[listcomp]==> listcomp:usetime=0.000005,alltime=0.000005
[listcomp]==> res[0]=0,res[-1]=8,len(res)=5 [listcomp]==> ---------------- 调用 listcomp 2-----------------
[listcomp]==> listcomp:usetime=0.002641,alltime=0.002646
[listcomp]==> res[0]=0,res[-1]=99998,len(res)=50000 [listcomp]==> ---------------- 调用 listcomp 3-----------------
[listcomp]==> listcomp:usetime=0.027689,alltime=0.030335
[listcomp]==> res[0]=0,res[-1]=999998,len(res)=500000 [listcomp]==> ---------------- 调用 listcomp 4-----------------
[listcomp]==> listcomp:usetime=0.052438,alltime=0.082773
[listcomp]==> res[0]=0,res[-1]=1999998,len(res)=1000000 (None, None, None, None)
>>> tuple(map(mapcall,xtpl))
[mapcall]==> ----------------- 调用 mapcall 1-----------------
[mapcall]==> mapcall:usetime=0.000004,alltime=0.000004
[mapcall]==> res[0]=0,res[-1]=8,len(res)=5 [mapcall]==> ----------------- 调用 mapcall 2-----------------
[mapcall]==> mapcall:usetime=0.003975,alltime=0.003979
[mapcall]==> res[0]=0,res[-1]=99998,len(res)=50000 [mapcall]==> ----------------- 调用 mapcall 3-----------------
[mapcall]==> mapcall:usetime=0.040665,alltime=0.044644
[mapcall]==> res[0]=0,res[-1]=999998,len(res)=500000 [mapcall]==> ----------------- 调用 mapcall 4-----------------
[mapcall]==> mapcall:usetime=0.098298,alltime=0.142942
[mapcall]==> res[0]=0,res[-1]=1999998,len(res)=1000000 (None, None, None, None)
>>> '{:.6f}'.format(mapcall.alltime)
'0.142942'
>>> '{:.6f}'.format(listcomp.alltime)
'0.082773'
>>> '{:.6f}'.format(mapcall.alltime/listcomp.alltime)
'1.726914'

相关文章:

python函数装饰器参数统计调用时间和次数

1 python函数装饰器参数统计调用时间和次数 python在函数装饰器外层定义一个函数生成封闭作用域来保存装饰器入参,供装饰器使用。 1.1 装饰器统计调用时间和次数 描述 通过类的可调用实例装饰器来统计函数每次调用时间和总调用时间,以及调用次数。 …...

机器学习之集成学习AdaBoost

概念 AdaBoost(Adaptive Boosting)是一种迭代的集成学习算法,其主要目标是通过组合多个弱学习器来创建一个强大的模型。以下是AdaBoost算法的主要步骤: 初始化样本权重: 为每个训练样本分配相等的权重,通常设为 w i = 1 N w_i = \frac{1}{N} w...

行云部署成长之路 -- 慢 SQL 优化之旅 | 京东云技术团队

当项目的SQL查询慢得像蜗牛爬行时,用户的耐心也在一点点被消耗,作为研发,我们可不想看到这样的事。这篇文章将结合行云部署项目的实践经验,带你走进SQL优化的奇妙世界,一起探索如何让那些龟速的查询飞起来!…...

Windows权限提升

0x01 简介 提权可分为纵向提权与横向提权: 纵向提权:低权限角色获得高权限角色的权限; 横向提权:获取同级别角色的权限。 Windows常用的提权方法有:系统内核溢出漏洞提权、数据库提权、错误的系统配置提权、组策略首…...

win系统搭建Minecraft世界服务器,MC开服教程,小白开服教程

Windows系统搭建我的世界世界服务器,Minecraft开服教程,小白开服教程,MC 1.19.4版本服务器搭建教程。 此教程使用 Mohist 1.19.4 服务端,此服务端支持Forge模组和Bukkit/Spigot/Paper插件,如果需要开其他服务端也可参…...

word2vec中的CBOW和Skip-gram

word2cev简单介绍 Word2Vec是一种用于学习词嵌入(word embeddings)的技术,旨在将单词映射到具有语义关联的连续向量空间。Word2Vec由Google的研究员Tomas Mikolov等人于2013年提出,它通过无监督学习从大规模文本语料库中学习词汇…...

在ios上z-index不起作用问题的总结

最近在维护一个H5老项目时,遇到一个问题,就是在ios上z-index不起作用,在安卓上样式都是好的。 项目的架构组成是vue2.x vux vuex vue-router等 用的UI组件库是vux 在页面中有一个功能点,就是点选择公司列表的时候,会…...

力扣labuladong一刷day59天动态规划

力扣labuladong一刷day59天动态规划 文章目录 力扣labuladong一刷day59天动态规划一、509. 斐波那契数二、322. 零钱兑换 一、509. 斐波那契数 题目链接:https://leetcode.cn/problems/fibonacci-number/description/ 思路:这是非常典型的一道题&#x…...

pyenv环境找不到sqlite:No module named _sqlite3

前言 一般遇到这个问题都在python版本管理或者虚拟环境切换中遇到,主要有两个办法解决,如下: 解决方法1 如果使用的pyenv管理python环境时遇到没有_sqlite3 库,可以将当前pyenv的python环境卸载 pyenv uninstall xxx然后在系统…...

Histone H3K4me2 Antibody, SNAP-Certified™ for CUTRUN

EpiCypher是一家为表观遗传学和染色质生物学研究提供高质量试剂和工具的专业制造商。EpiCypher推出的CUT&RUN级别的Histone H3K4me2 Antibody符合EpiCypher的批次特异性SNAP-CertifiedTM标准,在CUT&RUN中具有特异性和高效的靶点富集。通过SNAP-CUTANA™K-Me…...

我用 Laf 开发了一个非常好用的密码管理工具

【KeePass 密码管理】是一款简单、安全简洁的账号密码管理工具,服务端使用 Laf 云开发,支持指纹验证、FaceID,N 重安全保障,可以随时随地记录我的账号和密码。 写这个小程序之前,在国内市场找了很多密码存储类的 App …...

windows项目部署

文章目录 一、项目部署1.1 先准备好文件1.2安装jdk1.3 配置环境1.4 安装tomcat1.5 MySQL安装本机测试的话:远程连接测试 1.6 项目部署 一、项目部署 1.1 先准备好文件 1.2安装jdk 下一步 下一步 下一步 1.3 配置环境 变量名:JAVA_HOME 变量值:jdk的…...

http首部

1. htttp 报文首部 报文结构为:首部 空行(CRLF)主体 在请求中 http报文首部由请求方法,URI,http版本,首部字段等构成 在响应中:状态码,http版本,首部字段3部分构成 2…...

2024.1.8 Day04_SparkCore_homeWork

目录 1. 简述Spark持久化中缓存和checkpoint检查点的区别 2 . 如何使用缓存和检查点? 3 . 代码题 浏览器Nginx案例 先进行数据清洗,做后续需求用 1、需求一:点击最多的前10个网站域名 2、需求二:用户最喜欢点击的页面排序TOP10 3、需求三&#x…...

09.简单工厂模式与工厂方法模式

道生一,一生二,二生三,三生万物。——《道德经》 最近小米新车亮相的消息可以说引起了不小的轰动,我们在感慨SU7充满土豪气息的保时捷设计的同时,也深深的被本土品牌的野心和干劲所鼓舞。 今天我们就接着这个背景&…...

DHCP,怎么在Linux和Windows中获得ip

一、DHCP 1.1 什么是dhcp DHCP动态主机配置协议,通常被应用在大型的局域网络环境中,主要作用是集中地管理、分配IP地址,使网络环境中的主机动态的获得IP地址、DNS服务器地址等信息,并能够提升地址的使用率。 DHCP作为用应用层协…...

读写锁(arm)

参考文章读写锁 - ARM汇编同步机制实例(四)_汇编 prefetchw-CSDN博客 读写锁允许多个执行流并发访问临界区。但是写访问是独占的。适用于读多写少的场景 另外好像有些还区分了读优先和写优先 读写锁定义 typedef struct {arch_rwlock_t raw_lock; #if…...

【第33例】IPD体系进阶:市场细分

目录 内容简介 市场细分原因 市场细分主要活动 市场细分流程 作者简介 内容简介 这节内容主要来谈谈 IPD 市场管理篇的市场细分步骤。 其中,市场管理(Market Management)是一套系统的方法。 用于对广泛的机会进行选择性收缩,...

response 拦截器返回的二进制文档(同步下载excel)如何配置

response 拦截器返回的二进制文档(同步下载excel)如何配置 一、返回效果图二、response如何配置 一、返回效果图 二、response如何配置 service.interceptors.response.use(response > {// 导出excel接口if (response.config.isExport) {return resp…...

为什么要使用云原生数据库?云原生数据库具体有哪些功能?

相比于托管型关系型数据库,云原生数据库极大地提高了MySQL数据库的上限能力,是云数据库划代的产品;云原生数据库最早的产品是AWS的 Aurora。AWS Aurora提出来的 The log is the database的理念,实现存储计算分离,把大量…...

大数据学习(132)-HIve数据分析

​​​​🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言&#x1f4…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...

【iOS】 Block再学习

iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...

如何通过git命令查看项目连接的仓库地址?

要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...

CMS内容管理系统的设计与实现:多站点模式的实现

在一套内容管理系统中,其实有很多站点,比如企业门户网站,产品手册,知识帮助手册等,因此会需要多个站点,甚至PC、mobile、ipad各有一个站点。 每个站点关联的有站点所在目录及所属的域名。 一、站点表设计…...

MeanFlow:何凯明新作,单步去噪图像生成新SOTA

1.简介 这篇文章介绍了一种名为MeanFlow的新型生成模型框架,旨在通过单步生成过程高效地将先验分布转换为数据分布。文章的核心创新在于引入了平均速度的概念,这一概念的引入使得模型能够通过单次函数评估完成从先验分布到数据分布的转换,显…...

篇章一 论坛系统——前置知识

目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构​编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...

7种分类数据编码技术详解:从原理到实战

在数据分析和机器学习领域,分类数据(Categorical Data)的处理是一个基础但至关重要的环节。分类数据指的是由有限数量的离散值组成的数据类型,如性别(男/女)、颜色(红/绿/蓝)或产品类…...