你正在使用哪个版本的Go( go version
)?
$ go version
go version devel go1.18-f154f8b Tue Jan 4 22:27:20 2022 +0000 darwin/amd64
这个问题在最新版本中是否会重现?
是的
你正在使用什么操作系统和处理器架构( go env
)?
go env
输出
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/gura/Library/Caches/go-build"
GOENV="/Users/gura/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/gura/go/pkg/mod"
GONOPROXY="*.uangel.com"
GONOSUMDB="*.uangel.com"
GOOS="darwin"
GOPATH="/Users/gura/go"
GOPRIVATE="*.uangel.com"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/gura/sdk/gotip"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/gura/sdk/gotip/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="devel go1.18-f154f8b Tue Jan 4 22:27:20 2022 +0000"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/gura/test/fp/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/y1/bngm83dj5_5dcsgh9yrwvpm00000gp/T/go-build228120003=/tmp/go-build -gno-record-gcc-switches -fno-common"
你做了什么?
$ git clone -b build-cache https://github.com/csgura/fp.git
$ cd fp
$ gotip clean -cache
$ du -hs ~/Library/Caches/go-build/
8.0K /Users/gura/Library/Caches/go-build/
$ gotip test ./...
$ du -hs ~/Library/Caches/go-build/
1.4G /Users/gura/Library/Caches/go-build/
你期望看到什么?
一个合理大小的构建缓存目录,或者
关于不正确使用泛型类型的警告。
你看到了什么?
$ du -hs ~/Library/Caches/go-build/
1.4G /Users/gura/Library/Caches/go-build/
请原谅我的英语不好。
这似乎也与这个问题有关。#50204
我编写了一些代数数据类型来测试Go 1.18的泛型。( https://github.com/csgura/fp.git )
运行测试后,我注意到构建缓存正在使用大量的磁盘空间。我想原因在于一些递归类型( HList和curry Func )以及使用类型参数的接口类型。当我修改代码使得泛型接口类型不返回其他泛型接口类型时,构建缓存的大小显著减小了。这个修复应用在主分支上。
$ git checkout master
$ gotip clean -cache
$ gotip test ./...
$ du -hs ~/Library/Caches/go-build/
176M /Users/gura/Library/Caches/go-build/
现在它不会成为一个问题,但我认为随着越来越多的项目使用泛型,它将成为一个大问题。
9条答案
按热度按时间yvgpqqbh1#
请提供一个使用以下命令生成大型输出的小型单一源文件:
kcrjzv8t2#
Here is a single file of about 1500 lines.
https://gotipplay.golang.org/p/kMBLHxigsDo
drnojrws3#
使用上述测试用例,
go tool compile foo.go
生成的文件大小为70173802字节。go tool link foo.o
生成的文件大小为2400985字节。因此,最终可执行文件的大小约为目标文件大小的3.5%。目标文件中最大的符号是
根据
go tool nm
,它的大小为30111字节。它没有出现在最终可执行文件中。实际上,目标文件中最大的100个符号都没有出现在可执行文件中。这可能按预期工作,但如果不是这样,CC @randall77@danscales 可以提供帮助。
wvt8vs2t4#
https://gotipplay.golang.org/p/8WZz12Ay6vz
It is almost the same code, but the Option, Try , HCons and Iterator types are changed to a struct type.
The object file size has been reduced to 17436020.
It seems that object files are created inefficiently when generic interfaces refer to each other.
I know that it works as expected,
but wouldn't it be better to output a warning message when an object file is created inefficiently like that?
Because I think It would be better not to use type parameters with interface types in the production to reduce compile time.
wfsdck305#
正如Ian的符号示例所示,当类型参数是嵌套的示例化类型,并且一些底层类型的描述(例如接口)很大时,这些符号对于示例化函数/方法的名称可以非常大。对于形状类型的名称(代表特定示例化将处理的所有类型的代理类型),我们使用共享底层类型的标准打印(通过LinkString)(例如
go.shape.int64_0
或go.shape.interface { M(); String() string }_0
或go.shape.struct { p.x int8; p.y float64 }_0
)。使用底层类型的名称是最简单的,这样我们就可以在包之间拥有唯一的名字。对于Go 1.19,我们可以尝试使用更短、唯一的但已缓存的名称,但然后我们可能需要额外的协调(使用构建缓存?)。或者,如果形状名称变得非常大(> 50个字符),也许我们可以用MD5哈希替换它?6za6bjd06#
当一个对象文件被创建得不高效时,输出警告信息不是更好吗?
不。这是发布说明的内容,而不是编译器警告。一切都正常工作,只是占用的空间比预期的要多。编译器从不会发出警告。
yduiuuwa7#
FWIW,我已经编写了一些测试来表明,尽管软件包存档确实更大(通常为2倍),但生成的二进制可执行文件显示没有真正的差异。
bq9c1y668#
这是1.18里程碑的内容;现在要转向1.19了吗?谢谢。
a2mppw5e9#
是的,我会移动到1.19。谢谢!