当前位置: 首页 > 后端技术 > PHP

Go1.20的那些事:PGO、编译速度、错误处理等新特性,你知道多少?

时间:2023-03-29 16:25:24 PHP

大家好,我是炸鱼。近日,Go1.20于2月1日正式发布。它来得很早。过去,它被推迟到月底。看了好几篇文章,发现还是做了很多功能的选择,增加了一些新的功能(比如:arena等)鸽子!怀疑Go团队2月份有事,或者计划休假?还是担心裁员影响工作交接?今天,我们快速回顾一下与我们比较相关的新特性,看看能不能升级到1.20。在编译速度提升之前,Go1.18正式发布了泛型。有喜有忧。虽然这样支持泛型,但是Go1.18的编译速度比Go1.17慢。会慢15-18%左右,速度下降很明显。通用特性,Go引以为豪的构建速度变慢了。恐怕施工后不能喝咖啡?本来说是在Go1.19修复的,pigeonhole。最后,当前版本已修复。以下测试报告:│117.results│118.results│119.results│tip.results││sec/op│sec/opvsbase│sec/opvsbase│sec/opvsbase│GoBuildKubelet52.58±0%56.54±1%+7.54%(p=0.000n=10)55.47±1%+5.50%(p=0.000n=10)51.41±1%-2.22%(p=0.000n=10)GoBuildIstioctl47.78±1%51.44±0%+7.65%(p=0.000n=10)50.89±5%+6.50%(p=0.000n=10)46.05±1%-3.62%(p=0.000n=10)GoBuildFrontend19.03±1%20.55±1%+7.99%(p=0.000n=10)20.04±0%+5.33%(p=0.000n=10)18.22±1%-4.27%(p=0.000n=10)geomean36.2939.10+7.72%38.39+5.77%35.07-3.37%在最新的Go1.20基准测试中,当前版本的构建速度与Go1.17保持一致。额外的编译器和垃圾收集器优化减少了内存开销并将整体CPU性能提高了2%。Go1.21将结束部分MacOS和Windows版本。Go1.20的更新公告还公布了重大更新通知,涉及macOS和windows操作系统。它们如下:Go1.20是最后一个支持在macOS10.13HighSierra或10.14Mojave上运行的版本。Go1.21将需要macOS10.15Catalina或更高版本。Go1.20是最后一个支持在任何版本的Windows7、8、Server2008和Server2012上运行的版本。Go1.21至少需要Windows10或Server2016。好家伙,看来我需要更新我的操作系统版本,否则下一个版本的Go将不欢迎我来编码。有需要的同学请尽快在下个版本前升级。从新版Go发行版瘦身开始,Go的$GOROOT/pkg目录将不再存放标准库的预编译包存档,Go发行版将迎来一轮瘦身。尺寸对比如下。Go1.20:Go1.19:比老版本小1/3左右,比较明显。PGO介绍从Go1.20开始,Go引入了Profile-guidedoptimization(PGO),翻译过来就是配置文件引导的优化,目前是预览版。PGO是一种编译器优化技术,可以在不更改业务代码的情况下提高应用程序的性能。在GoPGO中,它会依赖runtime/pprof生成的配置文件来完成。结果是Go工具(工具链)可以根据运行时信息执行特定于应用程序和工作负载的优化。说明我想在不改动业务代码的情况下提升性能。详见:《PGO 是啥,咋就让 Go 更快更猛了?》支持封装多个错误。新增修改原有Go1.13错误API。核心是支持一个错误可以封装多个错误的特性。新功能示例:funcmain(){err1:=errors.New("err1")err2:=errors.New("err2")err:=errors.Join(err1,err2)fmt.Println(err)如果出错.Is(err,err1){fmt.Println("erriserr1")}iferrors.Is(err,err2){fmt.Println("erriserr2")}}输出结果:err1err2erriserr1erriserr2specific详见:《Go1.20 继续小修小补 errors 库。。。》AddedStringData,String,SliceDataGo团队通过分析搜索发现reflect.SliceHeader和reflect.StringHeader:typeStringHeaderstruct{DatauintptrLenint}业界经常滥用,使用不方便,而且很容易出现隐患。例如:数据字段类型是uintptr而不是unsafe.Pointer。什么都可以设置,灵活性太高,非常容易出问题。从Go1.20开始,unsafe标准库新增了3个函数来替代之前两种类型的使用。希望这将进一步标准化并提供额外的类型安全。函数签名如下:funcString(ptr*byte,lenIntegerType)string:根据数据指针和字符长度构造一个新的字符串。funcStringData(strstring)*byte:返回指向字符串字节数组的数据指针。funcSliceData(slice[]ArbitraryType)*ArbitraryType:返回切片的数据指针。新版本的用法变为:funcStringToBytes(sstring)[]byte{returnunsafe.Slice(unsafe.StringData(s),len(s))}funcBytesToString(b[]byte)string{returnunsafe.String(&b[0],len(b))}常用的reflect.SliceHeader和reflect.StringHeader会被标记为废弃。详见:《别乱用了,用新的。Go SliceHeader 和 StringHeader 将会被废弃!》优化时间对比和格式化内存2006-01-0215:04:05有很多围棋同学一直记得2006-01-0215:04:05,找到了这个日期时间点,使用次数很高:排名频率格式为175616time.RFC3339223954time.RFC3339Nano313312"2006-01-0215:04:05"412332"2006-01-02"511940time.RFC1123使用的频率数据是有根据的.Go1.20增加了以下常量直接引用:DateTime="2006-01-0215:04:05"DateOnly="2006-01-02"TimeOnly="15:04:05"Time.Compare增加时间比较方法.在目前的标准库中,有3种比较time.Time对象的方法,分别是:Before()、Equal()和After(),它们在功能上类似于<、==和>。但是缺少<=和>=的等价物。Go1.20会支持Time.Compare来实现类似的效果。效果是比较Time对象t和u。func(tTime)Compare(uTime)int此方法返回以下结果之一:-1如果t先于u。如果t在u之后,返回+1。如果它们相同则返回0。详见:《Go1.20 中两个关于 Time 的更新,终于不用背 2006-01-02 15:04:05 了!》禁止循环导入匿名接口。之前可以做匿名接口循环导入的show操作。如下代码:typeIinterface{m()interface{I}}这段代码声明接口类型I,然后包含m(),再包含接口I。这将是一个永不停止的“永动机”.在开源的GitHub中,它是真实存在的。从Go1.20开始,编译器默认会拒绝匿名接口的循环导入。如果没有用户反馈有重大影响或问题,计划在Go1.22正式禁用并移除对该功能的支持。详见:《Go1.20 将禁止匿名接口循环导入!》NoCtoolchaindisablesCGObydefaultGo1.20将在没有Ctoolchain的系统上默认禁用CGO。这在理论上是一种不兼容设置。如果需要,可以提前设置CGO_ENABLED环境变量,避免一些应用出现问题。支持切片转数组Go1.20支持切片转数组。以下代码:funcmain(){v:=[]string{"fried","fish","in","brain","children","a"}s:=[6]string(v)fmt.Println(s)}当然,前提是切片和数字的长度和类型必须正确。否则会出现如下错误:panic:runtimeerror:cannotconvertslicewithlength5toarrayorpointertoarraywithlength6goroutine1[running]:main.main()/tmp/sandbox1162344488/prog.go:9+0x1d程序退出。总结在Go1.20的这次更新中,比较有意思的是PGO的预览版。您有机会体验在不更改代码的情况下提高应用程序性能的快感。一些相关的更新正在偿还技术债务。比如:编译加速等。比较受关注的区,之前在《打脸了兄弟们,Go1.20 arena 来了!》分享过。经过具体的实现和分析,Go团队发现现有API存在严重问题,临时回滚了迭代代码,于是发布了鸽子。这个我打算以后单独分享。特别需要注意的是,从Go1.21开始,将不再支持macOS和windows的部分版本。可能有些公司的机器,甚至是自己的机器,都会提前升级。如果想查看完整的发布记录,可以阅读:https://go.dev/doc/go1.20。文章持续更新中。可以微信搜索【脑补炸鱼】阅读。本文已收录在GitHubgithub.com/eddycjy/blog中。学习Go语言可以看Go学习地图和路线。欢迎星星提醒。Go书系列Go语言入门系列:初探Go项目实战Go语言编程之旅:深入使用Go做项目Go语言设计哲学:理解Go的Why与设计思维Go语言进阶之旅:进一步深入-深度围棋源码推荐阅读增加实力!Go将增强Go1的向后兼容性。兄弟们,Go1.20竞技场来了!Go十年,终于想起统一日志库!