如何在编译时删除未使用的代码? [英] How to remove unused code at compile time?
问题描述
它使用标准的 import(package-name )
方法。
在编译时,我们的所有实用程序(包括非常小的实用程序)都以非常大的二进制文件结尾。 / p>
我们已经提取了实用程序中的所有字符串,并发现整个程序包正在被编译到每个实用程序中。包括那些实用程序没有使用的函数。
编辑1:
感谢回答此问题的人。
以下是我们所看到的内容:
main.go
包主
导入play / subplay
func main(){
subplay.A()
}
play / subplay.go
func A(){
fmt.Printf(这是函数A())
}
func B(){
fmt.Printf(secret string)
}
函数B从未打过电话然而,在构建二进制文件后,我们在main.exe中找到字符串secret string。
在编译时如何从Go程序中删除未使用的代码?
编译器已经这样做了。所有代码都以包文件结尾( .a
),但是在可执行文件中,Go工具不包括导入包中的所有内容,只包含需要的内容(更确切地说:它排除了它可以证明无法访问的东西)。
查看可能的重复拆分客户端/服务器代码。
这里需要注意的一点是:如果导入的包(您只想从中包括你引用的东西)导入其他包,这当然是递归的。
例如,如果你导入这个包:
包子播放
func A(){}
并且没有任何要求:
包主
import _play / subplay
func main(){
}
结果二进制文件(Go 1.8,linux,amd64)将为960,134字节(大致为1美元)。
如果您将 subplay
更改为导入 net / http
:
$ b $ c>
但是仍然不会调用 net / http
中的任何内容,结果将会是: 5,370,935字节(大约5 MB)! (请注意, net / http
也会导入 39个其他包!
现在,如果您继续并开始使用 net / http
中的内容:
包子播放
导入net / http
func A() {
http.ListenAndServe(,nil)
}
main
包仍然不会调用 subplay.A()
,可执行二进制文件的大小不改变:仍然是5,370,935字节
当您更改主要
包以调用 subplay.A()
:
包主
$ p
importplay / subplay
func main(){
subplay.A()
}
结果二进制增长:5,877,919字节!
如果更改
http.ListenAndServe()
到http.ListenAndServeTL S()
:func A(){
http.ListenAndServeTLS( ,,,无)
}
结果二进制文件是: 6,041,535字节
正如您所看到的,编译到可执行二进制文件中的内容取决于您调用/使用导入的包。
另外不要忘记Go是一种静态链接语言,结果可执行二进制文件必须包含它需要的所有东西。请参阅相关问题:编译的大小的原因() Go的可执行文件
We've built a Go package that is used by many of us.
It's imported using the standard
import ("package-name")
method.At compile time though, all of our utilities, including the very small ones, end up as very large binaries.
We've extracted all the strings in the utilities and discovered that the entire package is being compiled into each and every utility. Including functions that are not being used by those utilities.
EDIT 1:
Thank you to the people who are responding to this question.
Here's what we are seeing:
main.go
package main import "play/subplay" func main() { subplay.A() }
play/subplay.go
package subplay func A() { fmt.Printf("this is function A()") } func B() { fmt.Printf("secret string") }
Function B() is never called. Yet, after building the binary, we find the string "secret string" into main.exe.
How can we remove unused code from Go programs at compile time?
解决方案The compiler already does this. All code ends up in package files (
.a
), but in the executable binary the Go tool does not include everything from imported packages, only what is needed (or more precisely: it excludes things that it can prove unreachable).See possible duplicate Splitting client/server code.
One thing to note here: if an imported package (from which you only want to include things you refer to) imports other packages, this has to be done recursively of course.
For example if you import this package:
package subplay func A() {}
And call nothing from it:
package main import _ "play/subplay" func main() { }
The result binary (Go 1.8, linux, amd64) will be 960,134 bytes (roughly 1 MB).
If you change
subplay
to importnet/http
:package subplay import _ "net/http" func A() {}
But still don't call anything from
net/http
, the result will be: 5,370,935 bytes (roughly 5 MB)! (Note thatnet/http
also imports 39 other packages!)Now if you go ahead and start using things from
net/http
:package subplay import "net/http" func A() { http.ListenAndServe("", nil) }
But in the
main
package you still don't callsubplay.A()
, the size of the executable binary does not change: remains 5,370,935 bytes!And when you change the
main
package to callsubplay.A()
:package main import "play/subplay" func main() { subplay.A() }
The result binary grows: 5,877,919 bytes!
If you change
http.ListenAndServe()
tohttp.ListenAndServeTLS()
:func A() { http.ListenAndServeTLS("", "", "", nil) }
Result binary is: 6,041,535 bytes.
As you can see, what gets compiled into the executable binary does depend on what you call / use from the imported packages.
Also don't forget that Go is a statically linked language, the result executable binary has to include everything it needs. See related question: Reason for huge size of compiled executable of Go
这篇关于如何在编译时删除未使用的代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!