2013-12-19 8 views
14

私はgolangに新たなんです。実行可能ファイルは81Mの周りにある、コンパイル後なぜこのコードはgo(約81M)で非常に大きな実行ファイルを生成するのですか?

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) 
} 

$ 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()関数が大きな実行ファイルを生成するのですか?それは実行時に呼び出されるべきで、時間をコンパイルするのではないでしょうか?

------------さらに調査-----------

@FUZxxlによって賢明、私はクリアでグローバル変数を使用するコードを変更し( )。今回はファイルサイズが正常に戻りました。したがって、グローバル変数は正しく.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 

------------最新の更新-----------

これまでのところ、これはコンパイラの問題だと思われます。バグが提出されました:https://code.google.com/p/go/issues/detail?id=6993あなたが興味があればそれをフォローアップすることができます。

それへの解決策があります前に、あなたはあなたの関数でx := Y{}を使用しないでください。

func (self *BigData) Clear() { 
- *self = BigData{} 
+ var zero BigData 
+ *self = zero 
} 

答えて

10

は80,000,000バイト= sizeof uint64 * 10 * 1000 * 1000バイナリにハードコードされるのアレイを引き起こしているClear()関数でBigData{}ようになります。この問題を回避するには、([email protected]のおかげで)です。

+0

答えてくれてありがとう。はい、それが原因です。しかし、なぜこれが起こったのですか?この関数は実行時にのみ呼び出されるべきですか?コンパイラが実行可能ファイルにハードコード化されたのはなぜですか? – Tyr

+2

私の推測では、 'BigDataは{}'コンパイル時定数であるため、コンパイラはそれがあなたに代わって最適化を行っていると考えていることです。 –

+1

@Andrey私はそれが "最適化"だとは思っていません。 – user2864740