

ここ１週間ぐらい前から、go言語でコードを書き始めた初心者です。

質問は、"go run"や"go buiold/install"などのコンパイル時間を短くする方法（作法）を知りたく質問しました。

少し現状を記しておきます。  
現在goを使って、プログラムを書いています。  
説明が分かりにくくなりますので、ここではmain.goとmypackage.goの２つファイルを作成している状況を仮定します。main.goにはfunc
main()があり、mypackage.goにはその他のfuncを書いています。

自分の行いたいことに対し、goの標準的なlibraryが使えないため、自分でfuncを多数作成し、それをまとめたファイル(mypackage.go)を作成しています。それをmain.goの中でimportで呼び込んで、プログラムの動作("go
run main.go")を確認しています。

この方法で、現在コードを作成・コンパイル・実行を行っていますが、  
mypackage.goが数百行を超えたあたりから、コンパイルに非常に長い時間(4-6分以上)かかってしまっていて困っています。mypackage.goのfuncをすべてmain.goに移植しても同じ結果でした。まだmypackage.goにfuncを書き足していく予定のため、今後さらにコンパイル時間がかかると予想します。

コンパイル時間の短縮についてwebで調べたところ、毎回mypackage.goを呼び込んでいることが、余計に時間がかかっているとの記述を見つけました。そこで、go
installしたあと、go
build/runする方法をとりました。この方法自体を行うと、install後のコンパイルに時間がかからなくなりますが、mypackage.goを手直ししたら、（当たり前ですが）また再度同じ動作をしないと手直し部分がプログラム結果に反映されません。

mypackage.goを手直ししながらすばやくコンパイルを行い、実行結果を見ることは可能でしょうか？  
コンパイル時間が短いということでgoを使い始めましたが、初歩の初歩で躓いており、お恥ずかしい限りです。皆様はどのように自作のmypackage.goを時間をかけずにコンパイルしているのでしょうか？

ご教授をお願いします。


CC BY-SA 3.0
2015-08-24T22:21:16.613
14814
2015-08-31T13:02:26.910
11048
question
go
golangのコンパイル時間について


@argus  
初心者のため、サイトの作法（回答方法）で不備があったことをお詫びします。

コンパイル時間が異常に長くなってしまう原因だと思われるものを見つけましたので、  
サンプルコードと共に記録用に残しておきます。

[code]

    sample.go:
    
    package main 
    import "fmt" 
    type ImgInfo struct { 
                 MaxColSize int
                 MaxRowSize int
                 GREEN [1040][1388]int//←原因はここでした。 
    } 
    
    func Show(Img ImgInfo) { 
         fmt.Println(Img.MaxColSize, Img.MaxRowSize) 
         Img.MaxColSize++
         /* GREENの計算(省略) */
         fmt.Println(Img.MaxColSize, Img.MaxRowSize) 
    } 
    
    func main() {
         Img := ImgInfo{} 
         Show(Img) 
    } 
    
[/code]

どうやら、行列を指定して2DMatrixを作成すると、コンパイル時間がかかることが分かりました。

今までは、C++のdynamic arrayの感じで使っていました。  
C++では固定長のarrayを設定しても、さほどコンパイル時間に影響を与えません（と思います）が、  
どうやら、go言語では固定長にすると、コンパイル時間が長くなることが分かりました。

例えば、上記のcodeを

[code]

    time go run sample.go
[/code]

のコマンドで動かしますと約11秒かかってしまいますが、原因部分を"GREEN [][]int"に変えたsample
codeを同様にコマンドで動かしますと、約0.2秒しかかかりません。（１０年落ちのserverで計算しています。）

なぜこんなにコンパイル時間が違うのか、勉強不足のため、分かりませ‌​ん。
実際には、このような行が多数あり、それぞれがコンパイル時間に影響を及ぼし、合計で６分もコンパイル時間がかかってしまっていたと思われます。これらの部分をすべて書き直したら、全体のコンパイル時間でも0.6秒ほどですんでいます。大変勉強になりました。これからもよろしくお願いします。


CC BY-SA 3.0
2015-08-27T00:10:59.467
14885
2015-08-27T00:10:59.467
11048
14814
answer


私の調べた限りでは、引数に巨大なオブジェクトを渡すとコンパイル時間が長くなります。

goはスタックフレームのガーベジコレクションに必要な情報を実行ファイル内に埋め込んでおり、引数のサイズが巨大になるとこのデータが肥大化します。

参考: <https://golang.org/doc/asm#runtime>

`go tool 6g -S
test.go`を実行してアセンブリを調べると、以下のようなデータが大量に埋め込まれていることが確認できます。このデータの出力がコンパイル時間に影響している可能性が高いと思います。

[code]

    gclocals·c0c23a3d90b7d84b1fe0b61ccfa2921d t=7 dupok size=1082660 value=0
            0x0000 03 00 00 00 84 0d 2c 00 55 55 55 55 55 55 55 55  ......,.UUUUUUUU
            0x0010 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
            0x0020 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
            0x0030 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
            0x0040 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
            0x0050 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
            0x0060 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
            0x0070 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
            0x0080 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
            0x0090 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
            ...
    
[/code]

値ではなくポインタを渡すことでこの問題は解消できます。

[code]

    func Show(Img *ImgInfo) { 
    
    } 
    
    func main() {
         Img := ImgInfo{} 
         Show(&Img) 
    }
    
[/code]


CC BY-SA 3.0
2015-08-27T14:29:37.400
14914
2015-08-27T14:29:37.400
3639
14814
answer