`Caché/IRIS` 代码优化效率提升十一条 - 持续更新

文章目录

  • `Caché/IRIS`代码优化效率提升十一条 - 持续更新
    • 汇总数据使用多维数组
    • `Global`取数据时需将`Global`先赋值变量
    • 将表达式直接返回
    • 使用块语法的运行效率要比点语法更快
    • 复杂的`if`逻辑条件,可以调整顺序,让程序更高效
    • 在循环中取不变的配置时,应使用全局变量进行缓存
    • 逻辑运算使用双逻辑运算符
    • 在数组中查找数据,使用内部数组%List
    • 定义常量时,使用宏速度更快
    • 初始化变量时,分开声明效率更快
    • 存储数据Global名称越短,效率越高
  • 实践

Caché/IRIS代码优化效率提升十一条 - 持续更新

  • 本篇文章为笔者开发过程中总结一些提升效率方案。
  • 本篇将逐条展示优化代码的示例。
  • 本篇不涉及SQL优化,例如创建索引等。
  • 本篇文章将会持续更新。

注:提供新的优化代码方案,请与我联系或底部留言。


准备数据

  • 创建测试表结构如下:
Class M.T.Person Extends (%Persistent, %Populate) [ ClassType = persistent, SqlRowIdName = id, SqlTableName = Person ]
{

Property MTName As %String(CAPTION = "名称", POPSPEC = "Name()") [ Aliases = {name}, SqlFieldName = MT_Name ];

Property MTAge As %Integer(CAPTION = "年龄", POPSPEC = "Integer(18,30)") [ Aliases = {age}, SqlFieldName = MT_Age ];

Property MTNo As %String(CAPTION = "身份证号", POPSPEC = "Integer(100000,999999)") [ Aliases = {no}, SqlFieldName = MT_No ];

Property MTMoney As %Integer(CAPTION = "薪水", POPSPEC = "Integer(3000,30000)") [ Aliases = {money}, SqlFieldName = MT_Money ];
}
  • 生成100w条数据用于测试
USER> w ##class(M.T.Person).Populate(1000000)
1000000

在这里插入图片描述

汇总数据使用多维数组

通常我们汇总数据时用临时Global,或者使用进程私有Global,实际上两者效率差不多,如果不跨进程使用时,可以将其替换为多维数组。代码运行效率提升一倍左右。

  • 反例
	for i = 1 : 1 : 1000000 {
		s money = $li(^M.T.PersonD(i), 5)
		s ^yx(i) = money
	}
	
	s ID = ""
	for {
		s ID = $o(^yx(ID))
		q:(ID = "")
		s amt = amt + ^yx(ID)
	}
  • 正例
	s amt = 0
	for i = 1 : 1 : 1000000 {
		s money = $li(^M.T.PersonD(i), 5)
		s yx(i) = money
	}
	
	s ID = ""
	for {
		s ID = $o(yx(ID))
		q:(ID = "")
		s amt = amt + yx(ID)
	}
  • 效率测试
ClassMethod OptimizeSummaryData()
{
	/* 全局变量 */
	s t1 = $zh
	
	k ^yx
	s amt = 0
	for i = 1 : 1 : 1000000 {
		s money = $li(^M.T.PersonD(i), 5)
		s ^yx(i) = money
	}
	
	s ID = ""
	for {
		s ID = $o(^yx(ID))
		q:(ID = "")
		s amt = amt + ^yx(ID)
	}
	s t2 = $zh
	w "全局变量:" _ (t2 - t1),!
	w amt,!
	
	/* 进程全局变量 */
	s t1 = $zh
	k ^||yx
	s amt = 0
	for i = 1 : 1 : 1000000 {
		s money = $li(^M.T.PersonD(i), 5)
		s ^||yx(i) = money
	}
	
	s ID = ""
	for {
		s ID = $o(^||yx(ID))
		q:(ID = "")
		s amt = amt + ^||yx(ID)
	}
	s t2 = $zh
	w "进程全局变量:" _ (t2 - t1),!
	w amt,!
	
	/* 多维数组 */
	s t1 = $zh
	k yx
	s amt = 0
	for i = 1 : 1 : 1000000 {
		s money = $li(^M.T.PersonD(i), 5)
		s yx(i) = money
	}
	
	s ID = ""
	for {
		s ID = $o(yx(ID))
		q:(ID = "")
		s amt = amt + yx(ID)
	}
	s t2 = $zh
	w "多维数组:" _ (t2 - t1),!
	w amt,!
}
USER> d ##class(M.Optimize).OptimizeSummaryData()
全局变量:.869142
16506476230
进程全局变量:.783454
16506476230
多维数组:.40313
16506476230
  • 测试100w数据汇总,可观察多维数组效率最高。
  • 本示例仅取单条数据进行汇总,在真实环境中效率会更高。

Global取数据时需将Global先赋值变量

因为Global存在磁盘上,所以每次直接通过Global取值会多次IO磁盘,如果将Global赋值变量,因为变量在内存当中,再通过变量取值。运行效率会更快。

  • 反例
	for i = 1 : 1 : 1000000 {
		s name = $li(^M.T.PersonD(i), 2)
		s age = $li(^M.T.PersonD(i), 3)
		s no = $li(^M.T.PersonD(i), 4)
		s money = $li(^M.T.PersonD(i), 5)
	}
  • 正例
	for i = 1 : 1 : 1000000 {
		s data = ^M.T.PersonD(i)
		s name = $li(data, 2)
		s age = $li(data, 3)
		s no = $li(data, 4)
		s money = $li(data, 5)
	}
  • 效率测试
ClassMethod OptimizeGlobalData()
{
	#; 直接根据Global取值
	s t1 = $zh

	for i = 1 : 1 : 1000000 {
		s name = $li(^M.T.PersonD(i), 2)
		s age = $li(^M.T.PersonD(i), 3)
		s no = $li(^M.T.PersonD(i), 4)
		s money = $li(^M.T.PersonD(i), 5)
	}
	
	s t2 = $zh
	w "直接根据Global取值:" _ (t2 - t1),!

	#;Global赋值变量取值
	s t1 = $zh

	for i = 1 : 1 : 1000000 {
		s data = ^M.T.PersonD(i)
		s name = $li(data, 2)
		s age = $li(data, 3)
		s no = $li(data, 4)
		s money = $li(data, 5)
	}
	
	s t2 = $zh
	w "将Global赋值变量取值:" _ (t2 - t1),!
}
USER>d ##class(M.Optimize).OptimizeGlobalData()
直接根据Global取值:.654173Global赋值变量取值:.25341
  • 通过示例可观察到,将Global赋值变量取值比直接根据Global取值效率提升更大。

将表达式直接返回

如果方法比较简单,可直接将表达式返回。不必将结果赋值变量,在将变量返回。也可将方法声明为表达式方法,添加关键字[ CodeMode = expression ]

  • 反例
ClassMethod Return()
{
	s date = $h
	q date
}
  • 正例
ClassMethod Return1()
{
	q $h
}
  • 效率测试
ClassMethod OptimizeReturn()
{
	#; 间接返回值
	s t1 = $zh
	for i = 1 : 1 : 1000000 {
		d ..Return()
	}
	
	s t2 = $zh
	w "间接返回值:" _ (t2 - t1),!

	#; 直接返回值
	s t1 = $zh
	for i = 1 : 1 : 1000000 {
		d ..Return1()
	}

	s t2 = $zh
	w "直接返回值:" _ (t2 - t1),!
}
USER>d ##class(M.Optimize).OptimizeReturn()
间接返回值:.22599
直接返回值:.153412

使用块语法的运行效率要比点语法更快

点语法为旧语法结构,非特殊情况下,请使用块语法。

  • 反例
	for i = 1 : 1 : 1000000 d
	.s index = i
  • 正例
	for i = 1 : 1 : 1000000 {
		s index = i
	}
  • 效率测试
ClassMethod OptimizeGrammar()
{
	#; 点语法
	s t1 = $zh
	
	for i = 1 : 1 : 1000000 d
	.s index = i

	s t2 = $zh
	w "点语法:" _ (t2 - t1),!

	#; 块语法
	s t1 = $zh
	
	for i = 1 : 1 : 1000000 {
		s index = i
	}

	s t2 = $zh
	w "块语法:" _ (t2 - t1),!
}
USER>d ##class(M.Optimize).OptimizeGrammar()
点语法:.024101
块语法:.008296

复杂的if逻辑条件,可以调整顺序,让程序更高效

判断条件应该按照条件出现频率依次排在前面,出现频率最少的应放在最后。

  • 反例
	for i = 1 : 1 : 1000000 {
		if (color = "blue")||(color = "green")||(color = "red") {
		
		}
		continue:(color = "blue")||(color = "green")||(color = "red")
	}
  • 正例
	for i = 1 : 1 : 1000000 {
		if (color = "red")||(color = "green")||(color = "blue") {
		
		}
		continue:(color = "red")||(color = "green")||(color = "blue")
	}
  • 效率测试
ClassMethod OptimizeLogicalCondition(color)
{
	#; 常用条件排最前
	s t1 = $zh
	
	for i = 1 : 1 : 1000000 {
		if (color = "red")||(color = "green")||(color = "blue") {
		
		}
		continue:(color = "red")||(color = "green")||(color = "blue")
	}


	s t2 = $zh
	w "常用条件排最前:" _ (t2 - t1),!

	#; 常用条件排最后
	s t1 = $zh
	
	for i = 1 : 1 : 1000000 {
		if (color = "blue")||(color = "green")||(color = "red") {
		
		}
		continue:(color = "blue")||(color = "green")||(color = "red")
	}

	s t2 = $zh
	w "常用条件排最后:" _ (t2 - t1),!
}

USER>d ##class(M.Optimize).OptimizeLogicalCondition("red")
常用条件排最前:.032289
常用条件排最后:.088599

在循环中取不变的配置时,应使用全局变量进行缓存

通常取固定配置时,应该放在循环外面来取。如果必须在循环当中取配置时,可使用全局百分比变量进行缓存,后续判断全局变量如果存在则直接返回。

  • 反例
ClassMethod Config1()
{
	h 0.001
	s config = $zv
	q config
}
  • 正例
ClassMethod Config()
{
	q:($d(%zConfig)) %zConfig
	h 0.001
	s config = $zv
	s %zConfig = config
	q config
}
  • 效率测试
ClassMethod OptimizeConfig()
{
	#; 取一次配置
	s t1 = $zh
	
	for i = 1 : 1 : 1000 {
		s str = ..Config()
	}

	s t2 = $zh
	w "取一次配置:" _ (t2 - t1),!

	#; 每次都取配置
	s t1 = $zh
	
	for i = 1 : 1 : 1000 {
		s str = ..Config1()
	}

	s t2 = $zh
	w "每次都取配置:" _ (t2 - t1),!
}

USER>d ##class(M.Optimize).OptimizeConfig()
取一次配置:.00034
每次都取配置:1.844951
  • 示例中取配置耗时0.01,当循环次数越多,耗时越久。用全局变量方式可大大提升效率。

逻辑运算使用双逻辑运算符

单逻辑运算符无论是否满足条件,都会把判断条件测试一遍,双逻辑运算符,满足即退出。所以代码运行效率更快。

  • 反例
	for i = 1 : 1 : 1000000 {
		continue:(color = "red")!(color = "green")!(color = "blue")
	}
  • 正例
	for i = 1 : 1 : 1000000 {
		continue:(color = "red")||(color = "green")||(color = "blue")
	}
  • 效率测试
ClassMethod OptimizeLogicalOperator(color)
{
	#; 常用条件排最前
	s t1 = $zh
	
	for i = 1 : 1 : 1000000 {
		continue:(color = "red")!(color = "green")!(color = "blue")
	}


	s t2 = $zh
	w "常用条件排最前:" _ (t2 - t1),!

	#; 常用条件排最后
	s t1 = $zh
	
	for i = 1 : 1 : 1000000 {
		continue:(color = "red")||(color = "green")||(color = "blue")
	}

	s t2 = $zh
	w "常用条件排最后:" _ (t2 - t1),!
}
USER> d ##class(M.Optimize).OptimizeLogicalOperator("red")
单逻辑运算符:.029142
双逻辑运算符:.017941

USER> d ##class(M.Optimize).OptimizeLogicalOperator("blue")
单逻辑运算符:.030231
双逻辑运算符:.030113

在数组中查找数据,使用内部数组%List

在数据中查找某个值推荐使用%LIST内部数组格式。

为什么不使用 [ 包含运算符,是因为包含运算符无法确切查找某个值,例如 str = "1,111,1111,1111" ,查找ID为11str用逗号分割的字符串里并不包含11,但是也返回1,所以并不准确。

  • 反例
	s array = ##class(%ListOfDataTypes).%New()
	d array.Insert("red")
	d array.Insert("blue")
	d array.Insert("green")
	
	for i = 1 : 1 : 1000000 {
		if (array.Find(str)) {
		
		}
	}
  • 正例
	s array = $lb("red","blue","green")
	for i = 1 : 1 : 1000000 {
		if ($lf(array, str)) {
		
		}
	}
  • 效率测试
ClassMethod OptimizeArray(str)
{
	#; %ListOfDataTypes数组
	s t1 = $zh
	
	s array = ##class(%ListOfDataTypes).%New()
	d array.Insert("red")
	d array.Insert("blue")
	d array.Insert("green")
	
	for i = 1 : 1 : 1000000 {
		if (array.Find(str)) {
		
		}
	}

	s t2 = $zh
	w "%ListOfDataTypes数组:" _ (t2 - t1),!

	#; %List数组
	s t1 = $zh
	
	s array = $lb("red","blue","green")
	for i = 1 : 1 : 1000000 {
		if ($lf(array, str)) {
		
		}
	}
	
	s t2 = $zh
	w "%List数组:" _ (t2 - t1),!
}
USER>d ##class(M.Optimize).OptimizeArray("green")
%ListOfDataTypes数组:.654175
%List数组:.049307

定义常量时,使用宏速度更快

定义全局常量时,可以使用参数也可以使用宏,由于宏为编译时直接替换代码,所以效率更高。

  • 反例
Parameter COLORS = "RED";
  • 正例
#define COLORS "RED"
  • 效率测试
Parameter COLORS = "RED";

ClassMethod OptimizeParameter()
{
	#define COLORS "RED"
	#; 取参数常量
	s t1 = $zh
	
	for i = 1 : 1 : 1000000 {
		s str = ..#COLORS
	}

	s t2 = $zh
	w "取参数常量:" _ (t2 - t1),!

	#; 取宏常量
	s t1 = $zh
	
	for i = 1 : 1 : 1000000 {
		s str = $$$COLORS
	}

	s t2 = $zh
	w "取宏常量:" _ (t2 - t1),!
}
USER> d ##class(M.Optimize).OptimizeParameter()
取参数常量:.024702
取宏常量:.013341

初始化变量时,分开声明效率更快

  • 反例
	for i = 1 : 1 : 1000000 {
		s (index, count, sum, amt) = str
	}
  • 正例
	for i = 1 : 1 : 1000000 {
		s index = str
		s count = str
		s sum = str
		s amt = str
	}
  • 效率测试
ClassMethod OptimizeInitVar(str)
{
	#; 分别初始化变量
	s t1 = $zh

	for i = 1 : 1 : 1000000 {
		s index = str
		s count = str
		s sum = str
		s amt = str
	}
	
	s t2 = $zh
	w "分别初始化变量:" _ (t2 - t1),!

	#; 统一初始化变量
	s t1 = $zh

	for i = 1 : 1 : 1000000 {
		s (index, count, sum, amt) = str
	}
	
	s t2 = $zh
	w "统一初始化变量:" _ (t2 - t1),!
	
	
	#; 一行初始化变量
	s t1 = $zh

	for i = 1 : 1 : 1000000 {
		s index = str, count = str, sum = str, amt = str
	}
	
	s t2 = $zh
	w "一行初始化变量:" _ (t2 - t1),!
}
USER>d ##class(M.Optimize).OptimizeInitVar("")
分别初始化变量:.015438
统一初始化变量:.043211
一行初始化变量:.015472

存储数据Global名称越短,效率越高

  • 反例
	s id = ""
	for {
		s id = $o(^Mumps.Table.Global.Name.Person(id))
		q:(id = "") 
		s data = ^Mumps.Table.Global.Name.Person(id)
	}
  • 正例
	s id = ""
	for {
		s id = $o(^Q.1(id))
		q:(id = "") 
		s data = ^Q.1(id)
	}
  • 效率测试
ClassMethod OptimizeGlobalName()
{
	k ^Mumps.Table.Global.Name.Person
	k ^Q.1
	for i = 1 : 1 : 1000000 {
		s ^Mumps.Table.Global.Name.Person(i) = i
		s ^Q.1(i) = i
	}
	
	/* 长Gloabl名称 */
	s t1 = $zh
	
	s id = ""
	for {
		s id = $o(^Mumps.Table.Global.Name.Person(id))
		q:(id = "") 
		s data = ^Mumps.Table.Global.Name.Person(id)
	}

	s t2 = $zh
	w "长Gloabl名称:" _ (t2 - t1),!
	
	/* 短Gloabl名称 */
	s t1 = $zh

	s id = ""
	for {
		s id = $o(^Q.1(id))
		q:(id = "") 
		s data = ^Q.1(id)
	}

	s t2 = $zh
	w "短Gloabl名称:" _ (t2 - t1),!
}
USER>d ##class(M.Optimize).OptimizeGlobalName()Gloabl名称:.25337Gloabl名称:.233512
 
USER>d ##class(M.Optimize).OptimizeGlobalName()Gloabl名称:.250933Gloabl名称:.231979

注:在能保证可读性的情况下,尽量把表定义Global名称简明扼要。

实践

经过上述学习,来优化以下以下代码吧。此代码300w条数据,完整输出需要运行大概4个小时。

试一试仅仅做代码优化效率能提升多少。

ClassMethod XXXExecute(ByRef qHandle As %Binary, startDate As %String, endDate As %String) As %Status
{
  
 Set repid=$I(^CacheTemp)
 Set qHandle=$lb(0,repid,0)
 Set ind=1
 q:startDate="" $$$OK
 q:endDate="" $$$OK 
 k ^||TMPDHCWL($j)
 d ..GetAdmByDate(startDate,endDate)
 s admRowid=""  f  s admRowid=$o(^||TMPDHCWL($j,"STADM",admRowid)) q:admRowid=""  d
 .s typeCode=""
 .s patientid=""
 .s visitsn=""
 .s visittype=""
 .s outpatientno=""
 .s visittimes=""
 .s visitcardno=""
 .s typeCode=$p(^||TMPDHCWL($j,"STADM",admRowid),"^",3)
 .s patientid=..GetPapmiNo(admRowid)
 .s visitsn=admRowid	
 .s outpatientno=$p(^PAADM(admRowid),"^",81)	
 .s visittimes=$p(..CountCurrentPat(admRowid),"^",1)	
 .s wlId="" f  s wlId=$o(^DHCWorkLoad(0,"PAADM",admRowid,wlId)) q:wlId=""  d
 ..s expensesn=""
 ..s arpbl=""
 ..s BCIRowid=""
 ..s invId=""
 ..s receiptno=""
 ..s ordersn=""
 ..s orddate=""
 ..s ordTime=""
 ..s expensedatetime=""
 ..s wlType=""
 ..s transactiontypecode=""
 ..s transactiontypename=""
 ..s mEc=""
 ..s itemtypecode=""
 ..s itemtypename=""
 ..s itemcode=""
 ..s itemname=""
 ..s accUomId=""
 ..s itemunit=""
 ..s itemunitprice=""
 ..s itemamount=""
 ..s itemtotalprice=""
 ..s expensesn=wlId
 ..s arpbl=$p(^DHCWorkLoad(wlId),"^",20)
 ..s BCIRowid=$o(^DHCBCI(0,"Bill",arpbl,""))         
 ..s invId=$p(^DHCBCI(BCIRowid),"^",1) 
 ..s receiptno=invId
 ..s ordersn=$p(^DHCWorkLoad(wlId),"^",21) 
 ..s orddate=$p(^DHCWorkLoad(wlId),"^",5)
 ..s ordTime=$p(^DHCWorkLoad(wlId),"^",6)
 ..s expensedatetime=$zd(orddate,3)_" "_$zt(ordTime,1)	 
 ..s wlType=$p(^DHCWorkLoad(wlId),"^",47)
 ..s transactiontypecode=wlType
 ..s mEc=$p(^DHCWorkLoad(wlId),"^",41)
 ..s itemtypecode=$p(^DHCTarC("EC",mEc),"^",3)  												
 ..s itemtypename=$p(^DHCTarC("EC",mEc),"^",2)  												
 ..b ;ywc00000
 ..s item=$p(^DHCWorkLoad(wlId),"^",22)
 ..s itemcode=$p($g(^DHCTARI(item)),"^",1)  													
 ..s itemname=$p($g(^DHCTARI(item)),"^",2) 														
 ..s accUomId=+$p($g(^DHCTARI(item)),"^",3)
 ..s itemunit=$p($g(^CT("UOM",accUomId)),"^",2) 												
 ..s itemunitprice=$p(^DHCWorkLoad(wlId),"^",14) 												
 ..s itemamount=$p(^DHCWorkLoad(wlId),"^",15) 													
 ..s itemtotalprice=$p(^DHCWorkLoad(wlId),"^",16) 												
 ..s extenddata1=""
 ..s extenddata2=""
 ..i $p(^PAADM(admRowid),"^",20)="C" d
 ...s recordstatus="0"	
 ..e  d
 ...s recordstatus="1"	
 ..d OutputRow
 k ^||TMPDHCWL($j)
 Set qHandle=$lb(0,repid,0)
 Quit $$$OK
 
OutputRow
	set Data=$lb(patientid,visitsn,visittype,visitcardno,outpatientno,visittimes,expensesn,receiptno,ordersn,expensedatetime,transactiontypecode,transactiontypename,itemtypecode,itemtypename,itemcode,itemname,itemunit,itemunitprice,itemamount,itemtotalprice,extenddata1,extenddata2,recordstatus)
 	Set ^CacheTemp(repid,ind)=Data
 	Set ind=ind+1
	quit
}

ClassMethod GetAdmByDate(startDate, endDate, Index = "Dis") As %String
{
	;b
 k ^||TMPDHCWL($j)
 i Index="Prt" d
 .d ..GetAdmFromInv(startDate,endDate)
 e  i Index="Dis" d
 .d ...GetAdmFromAdm(startDate,endDate)
 e  i Index="MriP" d
 .d ...GetAdmFromMriP(startDate,endDate)
 e  i Index="MrInfo" d
 .d ..GetAdmFromMrinfo(startDate,endDate)
 e  i Index="EPR" d
 .d ..GetAdmFromEPRLoad(startDate,endDate)
 
 
 S num1=0
 s num2=0
 s num3=0
 s mFlag=0
 s paAdm=""  f  s paAdm=$o(^||TMPDHCWL($j,"ADM",paAdm))  q:paAdm=""  d
 .s typeCode=$p(^||TMPDHCWL($j,"ADM",paAdm),"^",3)
 .;w typeCode,!
 .;q:typeCode'="I"
 .i (typeCode="O")||(typeCode="E") d
 ..;s mFlag=..GetDiagFlagO(paAdm)
 ..;s num1=num1+1
 .e  d
 ..;s mFlag=..GetDiagFlagI(paAdm)
 ..;s num2=num2+1
 .;q:mFlag=0	
 .;s num3=num3+1
 .s ^||TMPDHCWL($j,"STADM",paAdm)=$g(^||TMPDHCWL($j,"ADM",paAdm))
 k ^||TMPDHCWL($j,"ADM")
 
 
 q 1
}

ClassMethod GetAdmFromInv(startDate, endDate) As %String
{
 s stDate=$zdh(startDate,3)
 s enDate=$zdh(endDate,3)
 f date=stDate:1:enDate d
 .s invId=0 f  s invId=$o(^DHCINVPRT(0,"Date",date,invId)) q:invId=""  d
 ..s time=$p(^DHCINVPRT(invId),"^",20)
 ..s BCIRowid=0 f  s BCIRowid=$o(^DHCBCI(0,"INV",invId,BCIRowid)) q:BCIRowid=""  d         
 ...s PBRowid=$p(^DHCBCI(BCIRowid),"^",2)
 ...s admId=$p(^DHCPB(PBRowid),"^",1)
 ...s type=$p(^PAADM(admId),"^",2)
 ...q:type="H"
 ...s ^||TMPDHCWL($j,"ADM",admId)=date_"^"_time_"^"_type
 .s invzyId=0 f  s invzyId=$o(^DHCINVPRTZY(0,"DATE",date,invzyId)) q:invzyId=""  d
 ..s admId=$p(^DHCINVPRTZY(invzyId),"^",4)
 ..s time=$p(^DHCINVPRTZY(invzyId),"^",3)
 ..s type=$p(^PAADM(admId),"^",2)
 ..s ^||TMPDHCWL($j,"ADM",admId)=date_"^"_time_"^"_type 
 q 1
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/7475.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringRetry接口异常优雅重试机制

场景&#xff1a; 某些场景下&#xff0c;如果接口出现异常需要进行重试&#xff0c;例如网络抖动、调用接口超时等并非接口代码导致的报错&#xff0c;此时可以进行接口重试机制 1、导入 spring retry 重试依赖 <!-- spring retry --><dependency><groupId>…

【Node.js】Express框架的基本使用

✍️ 作者简介: 前端新手学习中。 &#x1f482; 作者主页: 作者主页查看更多前端教学 &#x1f393; 专栏分享&#xff1a;css重难点教学 Node.js教学 从头开始学习 目录 初识Express Express简介 什么是Express 进一步理解 Express Express能做什么 Express的基本使用 …

分享:如何给 DBA 减负?

欢迎访问 OceanBase 官网获取更多信息&#xff1a;https://www.oceanbase.com/ 本文来自OceanBase社区分享&#xff0c;仅限交流探讨。原作者肖杨&#xff0c;OceanBase 软件开发工程师。 研发、数据分析师及运维内部人员有数据查询、数据订正等需求&#xff0c;若无管控平台&…

Midjourney 使用总结

1.关键词提问 中国古典女性&#xff0c;东方美女极致面容站在运河码头遥望丈夫&#xff0c;史诗奇幻场景风格&#xff0c;深绿浅棕&#xff0c;细节风帆&#xff0c;柔焦&#xff0c;人像隐喻&#xff0c;4K&#xff0c;电影级高品质照片&#xff0c;全景图&#xff0c; 焦距 …

突破市场壁垒:如何利用关键词采集和市场调查找到你的细分市场?

在市场竞争日益激烈的今天&#xff0c;寻找一个适合自己的细分市场成为了每个企业和创业者的必要之举。然而&#xff0c;许多人在寻找细分市场时陷入了困境&#xff0c;不知道如何找到一个符合自己产品的市场&#xff0c;因此&#xff0c;在这种情况下&#xff0c;利用关键词采…

UVM response_handler和get_response机制

很多UVM用户平时更多的使用get_response()方式去获得uvm_driver的response&#xff0c;但get_response有些缺点&#xff1a;由于 get_response() 是一种阻塞方法&#xff0c;它会阻塞直到收到来自 UVM 驱动程序 (put_response()) 的响应。因此&#xff0c;如果我们使用 get_res…

CleanMyMac X4.20最新mac电脑优化工具好用吗?

如果你的Mac运行速度变慢&#xff0c;很有可能是因为RAM内存被过度占用了。本文将向Mac用户&#xff0c;尤其是小白用户归纳一些常见的Mac内存清理方法。通过释放RAM内存&#xff0c;你将会看到自己Mac的运行速度有显著提升。 你的Mac运行速度是否变得慢到让人抓狂&#xff1f;…

项目下载中心-超简单版解决方案

简单的下载中心的设计流程 直接上设计流程&#xff1a; 以上就是步骤了&#xff0c;至于每个步骤怎么实现&#xff0c;那方法就很多了 &#xff0c;随意&#xff0c;达到目的就行。 至于各种问题&#xff0c;比如队列性能&#xff0c;消息重复或丢失&#xff0c;等等&#…

130亿参数,8个A100训练,UC伯克利发布对话模型Koala

平替再平替&#xff0c;可以在消费级 GPU 上运行的 Koala 模型能实现 ChatGPT 一半的性能。 自从 Meta 发布并开源了 LLaMA 系列模型&#xff0c;来自斯坦福大学、UC 伯克利等机构的研究者们纷纷在 LLaMA 的基础上进行「二创」&#xff0c;先后推出了 Alpaca、Vicuna 等多个「…

Solon v2.2.7 发布,支持 Java 20

Solon 是一个高效的 Java 应用开发框架&#xff1a;更快、更小、更简单。也是一个有自己接口标准规范的开放生态。 150来个生态插件&#xff0c;覆盖各种不同的应用开发场景&#xff1a; 相对于 Spring Boot 和 Spring Cloud 的项目&#xff1a; 启动快 5 &#xff5e; 10 倍…

【无功优化】基于改进遗传算法的电力系统无功优化研究【IEEE30节点】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

4.5--计算机网络之基础篇--1.模型分层--(复习+深入)---好好沉淀,加油呀

1.TCP/IP模型的分层 1.1.为什么要有 TCP/IP 网络模型&#xff1f; 对于同一台设备上的进程间通信&#xff0c;有很多种方式&#xff0c;比如有管道、消息队列、共享内存、信号等方式&#xff1b; 而对于不同设备上的进程间通信&#xff0c;就需要网络通信&#xff0c;而设备是…

2021蓝桥杯真题大写 C语言/C++

题目描述 给定一个只包含大写字母和小写字母的字符串&#xff0c;请将其中所有的小写字母转换成大写字母后将字符串输出。 输入描述 输入一行包含一个字符串。 输出描述 输出转换成大写后的字符串。 输入输出样例 示例 输入 LanQiao 输出 LANQIAO 评测用例规模与约定 对于…

python 生成器、迭代器、动态新增属性及方法

目录 一、生成器 1、生成器定义 2、生成器存在的意义 3、创建生成器方式一&#xff08;生成器表达式&#xff09; 4. 创建生成器方式二&#xff08;生成器函数&#xff09; 1. 生成器函数 2. 生成器函数的工作原理 5. 总结 1. 什么是生成器 2. 生成器特点 二、迭代器…

365天深度学习训练营-第J8周:Inception v1算法实战与解析

目录 一、前言 二、论文解读 1. Inception 模块 2. 网络深度问题 3. 全局平均池化 4. 卷积层的并行结构 5. 1x1 卷积核 6.详细的网络结构 三、代码复现 一、前言 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#x…

微服务+springcloud+springcloud alibaba学习笔记【Eureka服务注册中心】(3/9)

Eureka服务注册中心 3/91、服务注册与发现1.1 什么是服务治理&#xff1a;1.2 什么是服务注册与发现&#xff1a;1.3 Eureka服务注册与发现2、单机版eureka2.1 创建module2.2改pom依赖2.3写yml配置文件:2.4主启动类2.5 修改服务提供者 cloud-provider-payment8001 模块&#xf…

Github库中的Languages显示与修改

目录 前言 【.gitattributes】文件 修改GitHub语言 前言 上传一个项目到GitHub时&#xff0c;发现显示的语言并非是自己项目所示的语言&#xff0c;这样的情况是经常发生的&#xff0c;为了能到达自己所需快速检索&#xff0c;或者是外部访问者能很好的搜索我们的项目&#…

Sentinel滑动时间窗限流算法原理及源码解析(中)

文章目录 MetricBucketMetricEvent数据统计的维度WindowWrap样本窗口实例 范型T为MetricBucket windowLengthInMs 样本窗口长度 windowStart 样本窗口的起始时间戳 value 当前样本窗口的统计数据 其类型为MetricBucket MetricBucket MetricEvent数据统计的维度 1、首先计算27t位…

【花雕学AI】09:发挥ChatGPT最大潜力——产生高质量内容的九种方法和建议

人工智能&#xff08;AI&#xff09;是当今科技领域最热门和最有前景的话题之一&#xff0c;它已经渗透到了我们生活和工作的方方面面&#xff0c;给我们带来了许多便利和惊喜。而在AI的众多分支中&#xff0c;自然语言处理&#xff08;NLP&#xff09;是最贴近人类的一个领域&…

6-python异常、错误、模块、包

文章目录1.异常2.错误3.模块4.包[综合练习]1.异常 打开一个不存在的文件会引发异常 FileNotFoundError: [Errno 2] No such file or directory: ‘D:/不存在的文件.txt’ fopen(file"D:/不存在的文件.txt",mode"r", encodingutf-8) print(f.read())&…