英文:
Why this code generate very big executable in go (around 81M)?
问题
我是你的中文翻译助手,以下是你提供的代码的翻译:
我对golang还不熟悉。我写了如下的代码:
package main
import (
"fmt"
)
const (
BIG_NUM = 10 * 1000 * 1000
)
type BigData [BIG_NUM]uint64
func (self BigData) String() string {
return fmt.Sprintf("%d\n", self[0])
}
func (self *BigData) Clear() {
*self = BigData{}
}
func main() {
data := new(BigData)
fmt.Println(data)
}
编译后,可执行文件大小约为81M:
$ ls -l
-rwxr-xr-x 1 tchen 522017917 81533376 Dec 19 08:44 test
-rw-r--r-- 1 tchen 522017917 290 Dec 19 08:44 test.go
当我移除Clear()函数时,可执行文件大小恢复正常。为什么Clear()函数会生成如此大的可执行文件?它应该在运行时调用,而不是编译时调用,对吗?
------------ 进一步调查 -----------
受@FUZxxl的启发,我修改了代码,在Clear()函数中使用了一个全局变量。这次文件大小恢复正常了。所以全局变量被正确地放置在.bss段中。
package main
import (
"fmt"
)
const (
BIG_NUM = 10 * 1000 * 1000
)
type BigData [BIG_NUM]uint64
var (
bigData = BigData{}
)
func (self BigData) String() string {
return fmt.Sprintf("%d\n", self[0])
}
func (self *BigData) Clear() {
*self = bigData
}
func main() {
data := new(BigData)
fmt.Println(data)
}
编译后的可执行文件:
$ ls -l
-rwxr-xr-x 1 tchen 522017917 1534384 Dec 19 10:55 test
-rw-r--r-- 1 tchen 522017917 318 Dec 19 10:55 test.go
------------ 最新更新 -----------
到目前为止,看起来这是一个编译器问题。已经提交了一个bug报告:https://code.google.com/p/go/issues/detail?id=6993。如果你感兴趣,可以跟进一下。
在找到解决方案之前,你应该避免在函数中使用x := Y{}
的方式。一个解决方法是(感谢ality@pbrane.org):
func (self *BigData) Clear() {
var zero BigData
*self = zero
}
英文:
I'm new to golang. I wrote code like this:
package main
import (
"fmt"
)
const (
BIG_NUM = 10 * 1000 * 1000
)
type BigData [BIG_NUM]uint64
func (self BigData) String() string {
return fmt.Sprintf("%d\n", self[0])
}
func (self *BigData) Clear() {
*self = BigData{}
}
func main() {
data := new(BigData)
fmt.Println(data)
}
After compiling, the executable is around 81M:
$ ls -l
-rwxr-xr-x 1 tchen 522017917 81533376 Dec 19 08:44 test
-rw-r--r-- 1 tchen 522017917 290 Dec 19 08:44 test.go
When I remove Clear() function, the executable goes to normal size. So why this Clear() function generate so big executable? It should be called at runtime, not compiling time, right?
------------ further investigation -----------
Enlightened by @FUZxxl, I modified the code to use a global variable in Clear(). This time the file size went back to normal. So global variables are putting to .bss section correctly.
package main
import (
"fmt"
)
const (
BIG_NUM = 10 * 1000 * 1000
)
type BigData [BIG_NUM]uint64
var (
bigData = BigData{}
)
func (self BigData) String() string {
return fmt.Sprintf("%d\n", self[0])
}
func (self *BigData) Clear() {
*self = bigData
}
func main() {
data := new(BigData)
fmt.Println(data)
}
The compiled executable:
$ ls -l
-rwxr-xr-x 1 tchen 522017917 1534384 Dec 19 10:55 test
-rw-r--r-- 1 tchen 522017917 318 Dec 19 10:55 test.go
------------ latest update -----------
So far it seems this is a compiler issue. A bug has been submitted: https://code.google.com/p/go/issues/detail?id=6993. You can follow up it if you're interested.
Before there's any solution to it, you should avoid using x := Y{}
in your function. A workaround is (thanks to ality@pbrane.org):
func (self *BigData) Clear() {
- *self = BigData{}
+ var zero BigData
+ *self = zero
}
答案1
得分: 10
在Clear()
函数中,BigData{}
似乎导致一个大小为80,000,000字节的数组被硬编码到二进制文件中,其大小为sizeof uint64 * 10 * 1000 * 1000
。
英文:
Looks like BigData{}
in the Clear()
function is causing an array of 80,000,000 bytes = sizeof uint64 * 10 * 1000 * 1000
to be hardcoded into the binary.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论