Go 1.20更新了那些内容
PGO的引入
Go 1.20 发布了配置文件引导优化(PGO)的预览版,使编译器能够根据运行时配置文件信息,执行应用程序和工作负载的特定性优化。提供要构建的配置文件,使编译器能够将应用程序的速度提高大约 3-4%,官方鼓励开发者尝试一下整个新特性,但可能存在一些未知的问题。
具体可参考:Profile-guided optimization: https://go.dev/doc/pgo
PGO 是计算机编程中的一种编译器优化技术,借助配置文件来引导编译,能够在不改业务代码的情况下,达到提高程序运行时性能的目的。
该优化是一门通用技术,不局限于某一门语言:
- Chrome 浏览器,在 64 位版本的 Chrome 中从 53 版开始启用 PGO, 32 位版在 54 版中启用。
- Microsoft Visual C++ 也同样有所使用。
- AutoFDO 进行了 PGO 的优化,直接将某数据中心中的 C/C++ 程序的性能提高了 5-15%(不用改业务代码)。
- 在 Go PGO 中将会依托 runtime/pprof 所生成的 profile 来完成。
PGO 怎么优化
PGO 通过缩小代码大小、减少代码分支错误预测和重新组织代码布局以减少指令缓存问题来提高应用程序性能。也可以向编译器提供有关应用程序中最常执行的区域的信息。
编译器再通过分析这些信息,编译器能够在优化应用程序时更具选择性和针对性,做出最优的选择。
PGO 由三个阶段组成。如下图:

检测程序:编译器从你的源代码和编译器的代码创建并链接一个检测程序。
运行检测的可执行文件:每次执行插桩代码时,插桩程序都会生成一个动态信息文件,用于最终编译。
最终编译:当你第二次编译时,动态信息文件将合并到一个摘要文件中。编译器会使用此文件中的概要信息,然后尝试选择程序中最频繁最优的运行路径去执行。
这就是 PGO 这项优化的基本过程了。
语言变化
- 切片可以直接转化为数组
unsafe包中添加了Slice,SliceData,String,StringData函数
切片转数组示例
package main
import "fmt"
func main() {
sli := []int{1, 2, 3, 4, 5}
arr := [5]int(sli)
fmt.Println(arr)
}
// 输出如下
// [1 2 3 4 5]
unsafe 包中新增函数原型
package unsafe
// Slice 根据指针参数和长度参数构造一个切片并返回
// 修改切片元素值会影响底层的数组元素值
func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
// SliceData 返回参数切片的指针
func SliceData(slice []ArbitraryType) *ArbitraryType
// String 根据指针参数和长度参数构造一个字符串并返回
// 修改参数指向的值会同时修改字符串的值
func String(ptr *byte, len IntegerType) string
// StringData 返回参数字符串底层的字节数组指针
func StringData(str string) *byte
下面是两个小例子,分别使用到了 Slice 函数和 String 函数。
使用 unsafe.Slice,根据数组生成切片
package main
import (
"fmt"
"unsafe"
)
func main() {
arr := [5]int{1, 2, 3, 4, 5}
// 注意: 这里是传递首个元素的指针,而非数组的指针
sli := unsafe.Slice(&arr[0], 3)
fmt.Printf("slice = %+v, len = %d\n", sli, len(sli))
// 修改切片元素的值会影响底层的数组
for i := range sli {
sli[i] *= 100
}
fmt.Printf("slice = %+v, len = %d\n", sli, len(sli))
// 此时数组的元素值已经变化
fmt.Printf("array = %+v, len = %d\n", arr, len(arr))
}
// 运行输出如下
// slice = [1 2 3], len = 3
// slice = [100 200 300], len = 3
// array = [100 200 300 4 5], len = 5
使用 unsafe.String,根据切片生成字符串
package main
import (
"fmt"
"unsafe"
)
func main() {
bs := []byte{'h', 'e', 'l', 'l', 'o'}
// 注意: 这里是传递首个元素的指针,而非切片的指针
str := unsafe.String(&bs[0], 2)
fmt.Printf("str = %s, len = %d\n", str, len(str))
// 修改参数指向的值会同时修改字符串的值
bs[1] = 'i'
// 此时字符串的值已经变化
fmt.Printf("str = %s, len = %d\n", str, len(str))
fmt.Printf("bs = %s, len = %d\n", bs, len(str))
}
// 运行输出如下
// str = he, len = 2
// str = hi, len = 2
// bs = hillo, len = 2
标准库增强
• 新增了几个 时间转换格式常量
• 新包 crypto/ecdh 支持通过 NIST 曲线和 Curve25519 椭圆曲线 Diffie-Hellman 密钥交换
• 新类型 http.ResponseController 访问 http.ResponseWriter 接口未处理的扩展请求
• httputil.ReverseProxy 包含一个新的 Rewrite 钩子函数,取代了之前的 Director 钩子
• 新方法 context.WithCancelCause 提供了一种方法来取消具有给定错误的上下文
• os/exec.Cmd 结构体中的新字段 Cancel 和 WaitDelay, 指定 Cmd 在其关联的 Context 被取消或其进程退出时的回调
errors.Join
新方法 errors.Join 返回一个错误列表,如果错误类型实现了 Unwrap() []error,则可以再次获得错误列表
在原有 Go1.13 的 errors API 上进行新增和修改,核心是支持一个错误可以封装多个错误的特性。新方法 errors.Join 返回一个错误列表,如果错误类型实现了 Unwrap() []error,则可以再次获得错误列表。
func main() {
err1 := errors.New("err1")
err2 := errors.New("err2")
err := errors.Join(err1, err2)
fmt.Println(err)
if errors.Is(err, err1) {
fmt.Println("err is err1")
}
if errors.Is(err, err2) {
fmt.Println("err is err2")
}
}
// 输出结果
err1
err2
err is err1
err is err2
优化时间比较和格式记忆
Go1.20 新增了几个 时间转换格式常量,便于直接引用:
package time
const (
DateTime = "2006-01-02 15: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 (t Time) Compare(u Time) int
该方法返回如下几种结果:
- 如果 t 在 u 之前,则返回 -1。
- 如果 t 在 u 之后,则返回 +1。
- 如果它们相同,则返回 0。
工具改进
• cover 工具可以收集整个程序的覆盖率,不仅仅是单元测试
• go build、go install 和其他与构建相关的命令可以接收一个 -pgo 标志,启用配置文件引导优化,以及一个 -cover 标志,用于整个程序覆盖率分析
• go test -json 的实现已得到改进,可以处理复杂多样的 Stdout 输出
• vet 在并行运行的测试中可能会发生更多循环变量引用错误
• 在没有 C 工具链 的系统上默认禁用 CGO
性能提升
• 编译器和 GC 的优化减少了内存开销,并将 CPU 性能整体提高了 2%
• 针对编译时间进行了优化,提升了 10%。使得构建速度与 Go 1.17 保持一致 (恢复到了泛型之前的速度)
• Go 发行版瘦身,新版本起,Go 的 $GOROOT/pkg 目录将不再存储标准库的预编译包存档,Go 发行版的将迎来一轮瘦身。
从 1.21 版本开始,一些较旧的操作系统将不再受支持:包括 Windows 7、8、Server 2008 和 Server 2012、macOS 10.13 High Sierra 和 10.14 Mojave。
Go 1.20更新了那些内容的更多相关文章
- SQL技巧两则:选择一个表的字段插入另一个表,根据其它表的字段更新本表内容
最近,在作django数据表迁移时用到的. 因为在django中,我把本来一个字符型字段,更改成了外键, 于是,哦喝~~~字符型字段相当于被删除了, 为了能导入这些字段的外键信息,于是出此下策. 其实 ...
- [转]MFC子线程中更新控件内容的两种办法
一.概述 每个系统中都有线程(至少都有一个主线程),而线程最重要的作用就是并行处理,提高软件的并发率.针对界面来说,还能提高界面的响应能力.一般的,为了应用的稳定性,在数据处理等耗时操作会单独在一个线 ...
- SQL通过Datatable更新数据库表内容
SQL通过Datatable更新数据库表内容 //要注意的一点是在Select语句中要选择的列中必须包含主键的列,此外不支持多表连接查询 DataTable dt = new DataTable( ...
- HMS Core 分析服务 6.4.1版本上线啦,快来看看更新了哪些内容。
更新概览 支持转化事件回传至华为应用市场商业推广,便捷归因,实时调优. 卸载分析模型支持用户卸载前事件和路径分析,深度剖析卸载根因. 实时漏斗体验开放,灵活定位异常流失. 详情介绍 更新一:全面开放深 ...
- DLNA介绍(包含UPnP,2011/6/20 更新)
这部分的内容大多来源于网络及官方文档,依照自己的翻译理解整理所成.东西比較多,从头慢慢看还是能够懂个大概的. 文件夹: 一.DNLA的建立 二.DLNA的成员 三.DLNA标准的制定 四.DLNA的设 ...
- [android更新类的内容开发APP]四、项目布局的基本功能(继续)
昨天,只拿到电脑,别说,眼泪 http://joveth.github.io/funny/ 1.选项卡的滑动效果 要知道.用这个选项卡就是想让它滑动起来,不然的话.我才不喜欢用它呢. 在让他滑动之前, ...
- poi 技术动态更新 Excel模板内容,动态更新内容
1.控制器方法 private URL base = this.getClass().getResource(""); /** * 流拍之后,可以下载询价单 * * @param ...
- 使用观察者模式更新Fragment的内容
最近有个需求,就是在Fragment没有切换的时候(show,hide)更新Fragment显示的内容,想了一会,终于想到可以用观察者模式来解决这个问题的. 定义一个[被观察者(接口)]: publi ...
- wordpress通过$wpdp更新数据表内容
如下面的代码 更新id为1的数据 table 指的是要更新的数据表 第一个数组 array( 'column1' => 'value1', 'column2' => 'value2' ) ...
- 关于Git在Visual studio及Git Bush中的日常操作教程,有图有说明,会一直更新本页内容... (Git相对SVN具有更加安全的分布式存储, 分支版本之间切换秒级速度, 分支版本强大灵活等特点)
>安装命令行和TortoiseGit UI程序. <git bash的安装> https://git-scm.com/downloads <windows可视化工具 Torto ...
随机推荐
- Qt编写地图综合应用18-地图模式
一.前言 除了传统的街道图地图外,默认的一般都是街道图,还有卫星图.三维图等,其中又有叠加层,比如叠加路况图层和路网图层等,最近去了多家的地图官网看对应的api接口,总体上感觉现在都往2.5D或者3D ...
- Qt开源作品5-仪表盘交互
一.前言 Echart是百度研发团队开发的一款报表视图JS插件,功能十分强大,是本人用过的国产作品中最牛逼的,记得四五年前就在qt中使用过,当时用的浏览器控件是webkit,由于5.6以后的版本不再支 ...
- 祝大家这周圣诞快乐!!本周进军多模态!😀From LLMs to MLLMs:😜Exploring the Landscape of Multimodal Jailbreaking
从LLMs到MLLMs:探索多模态越狱攻击的前景 禁止盗用,侵权必究!!!欢迎大家积极举报 ①脆弱性代表:越狱攻击(恶意指令/训练&解码干预). ②最近的越狱攻击: 整体说:构建越来越复杂场景 ...
- Llama3.1 是怎么工作哒?原文翻译版😘
了解Llama3.1如何工作--深入探讨模型流程 原文标题:Understand How Llama3.1 Works - A Deep Dive Into the Model Flow 原作者:Xi ...
- Web网页端IM产品RainbowChat-Web的v7.0版已发布
一.关于RainbowChat-Web RainbowChat-Web是一套Web网页端IM系统,是RainbowChat的姊妹系统(RainbowChat是一套基于开源IM聊天框架 MobileIM ...
- 阿里IM技术分享(七):闲鱼IM的在线、离线聊天数据同步机制优化实践
本文由阿里闲鱼技术团队书闲分享,原题"如何有效缩短闲鱼消息处理时长",有修订和改动,感谢作者的分享. 1.引言 闲鱼技术团队围绕IM这个技术范畴,已经分享了好几篇实践性总结文章,本 ...
- 21. C++快速入门--协程 Coroutine 入门
参考: https://www.cnblogs.com/blizzard8204/p/17563217.html https://www.bennyhuo.com/2022/03/09/cpp-cor ...
- 老生常谈——分布式限流:部分Sentinal源码解读
基础知识 HTTP CODE = 429 "请求过多" A. 限流的类型 服务端 客户端 限流的标的 IP 用户 ... 基本要求 准确限制过量的请求. 低延时.限流器不能拖慢HT ...
- 前端学习openLayers配合vue3(获取矢量图的个数,省份的个数)
矢量图层绘制了一个中国地图,我们获取一下矢量图层的个数 关键代码 map .getLayers()//获取所有图层 .item(1)//获取矢量图层 .getSource() .on("ch ...
- elsa工作流-调度(安排后台作业)
前言 elsa内部很多地方都会用到后台作业,也就是在后台线程中执行一堆任务,这与我们通常理解的后台作业没有区别. elsa将后台作业也称为调度Schedul,相关功能由Elsa.Scheduling模 ...