47

Go 1.15 正式发布:看看都有哪些值得关注的变化

 4 years ago
source link: https://mp.weixin.qq.com/s/AdB5jxMj6fBQBY0KMbazVQ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

刚刚 Go Team 宣布 Go 1.15 正式发布。受疫情影响,这次版本变化的内容不太多,但如期发布了。

它的大部分更改在工具链、运行时和库的实现。与往常一样,该版本保留了 Go 1 兼容性的承诺。这几乎保证所有的 Go 程序都能像以前一样正常编译和运行。

Go 1.15 包括对链接器的重大改进,改进了对具有大量内核的小对象的分配,并弃用了 X.509 CommonName。GOPROXY 现在支持跳过返回错误的代理,并添加了新的嵌入式 tzdata 包。

我们一起看看具体都有哪些值得关注的变化。

1、新的链接器

官方的设计文档地址:https://golang.org/s/better-linker,从命名看,是一个更好的链接器(这是废话)。

此版本 Go 可减少链接器资源的使用(时间和内存)并提高代码的健壮性/可维护性。对于在 amd64 架构上运行的基于 ELF 的操作系统(Linux,FreeBSD,NetBSD,OpenBSD,Dragonfly 和S olaris),代表性的大型 Go 程序集的链接速度提高 20%,平均所需内存减少 30%。其他体系结构/OS 组合的改进。改进链接程序性能的关键因素是新设计的目标文件格式,以及内部阶段的改进以提高并发性(例如,将重定位并行应用于符号)。Go 1.15 中的目标文件比其 1.14 等价文件稍大。这些更改是对 Go 链接器进行现代化改造的多版本项目的一部分,这意味着将来的版本中有望对链接器进行其他改进。现在,链接器在 linux/amd64和 linux/arm64 上默认为 -buildmode=pie 的内部链接模式,因此这些配置不再需要 C 链接器。

2、编译器改进,包括略微小了些的二进制文件

包 unsafe 的安全规则[1]允许在调用某些函数时将 unsafe.Pointer 转换为 uintptr。以前,在某些情况下,编译器允许进行多个链式转换(例如 syscall.Syscall(…,uintptr(uintptr(ptr)),…))。编译器现在只需要一次转换。使用多次转换的代码应进行更新以满足安全规则。

与 Go 1.14 相比,Go 1.15 通过消除某些类型的 GC 元数据和更积极地消除了未使用的类型元数据,与 Go 1.14 相比将典型的二进制大小减少了大约 5%。该工具链现在通过将函数与 32 字节边界对齐并填充跳转指令来缓解 GOARCH=amd64 上的 Intel CPU 勘误 SKX102[2]。尽管此填充增加了二进制大小,但这远远超出了上述二进制大小改进所弥补的范围。

Go 1.15 向编译器和汇编器都添加了 -spectre 标志,以允许启用 Spectre 缓解措施。这些几乎是绝对不需要的,主要是作为“纵深防御”机制提供的。有关详细信息,请参见 Spectre Wiki页面[3]。

现在,编译器将拒绝 //go: compiler 指令,这些指令对其所使用的声明无意义,并出现“放错位置的编译器指令”错误。此类错误使用的指令以前已被破坏,但编译器无声地忽略了它们。

现在,编译器的 -json 优化日志记录报告大(>= 128 字节)副本,并包含转义分析决策的说明。

3、内嵌 tzdata(时区数据)

增加了一个新包:time/tzdata,当系统找不到时区数据时(比如 Windows 等),通过导入这个包,在程序中内嵌时区数据,也可以通过编译时传递  -tags timetzdata 来实现同样的效果。

具体查看这个 issue:https://github.com/golang/go/issues/38017 以及包 time/tzdata 的说明:https://golang.org/pkg/time/tzdata/。

4、增加 testing.TB.TempDir

测试生成临时文件挺常见的,这个为了更好的解决此问题。详情见 issue:https://github.com/golang/go/issues/35998。

5、增加 testing.T.Deadline

将 context 引入 testing 包。详情见 issue:https://github.com/golang/go/issues/28135。

6、关于 Ports 部分

darwin/386、darwin/arm 不再支持;riscv64 变得更好;linux/arm64 现在作为第一类 port 支持。

7、API 的变动

1)net/url.URL RawFragment 和 EscapedFragment ,详情见 issue:https://github.com/golang/go/issues/37776;

2)net/url.URL.Redacted,详情见 issue:https://github.com/golang/go/issues/34855;

3)time.Ticker.Reset,我们知道 Timer 是有 Reset 的,这次为 Ticker 也增加,详情见 issue:https://github.com/golang/go/issues/33184;

4)regexp.Regexp.SubexpIndex,详情见 issue:https://github.com/golang/go/issues/32420;

5)sync.Map.LoadAndDelete,详情见 issue:https://github.com/golang/go/issues/33762;

6)crypto/tls.Dialer.DialContext,详情见 issue:https://github.com/golang/go/issues/18482;

还有其他一些 API 变动,不一一列举。

8、工具链

1)增加 go env GOMODCACHE:https://github.com/golang/go/issues/34527;

2)opt-in fallbacks in GOPROXY:https://github.com/golang/go/issues/37367;

3)vet:warn about string(int) 和 detect impossible interface assertions:https://github.com/golang/go/issues/32479 和 https://github.com/golang/go/issues/4483;

4)println 允许打印两个值。println(twoValues());

5)panic:显示可打印的值而不是地址。比如:

type MyString stringpanic(MyString("hello"))

现在打印:

panic: (main.MyString) (0x48aa00,0x4c0840)

期望打印:

panic: main.MyString("hello")

可读性会好很多。

1)在 amd64 上更好的写屏蔽;

2)在 Linux 上,forkAndExec 使用 dup3;

3)sha512 算法速度提升 15%;

4)ReadMemStats 延迟降低 95%;

5)关闭状态的 channel 接收速度提升 99%;

6)将小的 int 值转为 interface{} 不额外分配内存;

10、更详细的改动

更多详细的改动,见官方发布文档 https://golang.org/doc/go1.15。今天稍后我会更新 studygolang 上的包下载和文档。

[1]

安全规则: https://golang.org/pkg/unsafe/#Pointer

[2]

勘误 SKX102: https://www.intel.com/content/www/us/en/support/articles/000055650/processors.html

[3]

Spectre Wiki页面: https://github.com/golang/go/wiki/Spectre


觉得不错,欢迎关注:

点个赞、在看和转发是最大的支持


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK