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 [email protected]):
func (self *BigData) Clear() {
- *self = BigData{}
+ var zero BigData
+ *self = zero
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With