如何在编译时删除未使用的代码? [英] How to remove unused code at compile time?

查看:256
本文介绍了如何在编译时删除未使用的代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



它使用标准的 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()

 包主

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 import net/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 that net/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 call subplay.A(), the size of the executable binary does not change: remains 5,370,935 bytes!

And when you change the main package to call subplay.A():

package main

import "play/subplay"

func main() {
    subplay.A()
}

The result binary grows: 5,877,919 bytes!

If you change http.ListenAndServe() to http.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆