質問: ここ1週間ぐらい前から、go言語でコードを書き始めた初心者です。 質問は、"go run"や"go buiold/install"などのコンパイル時間を短くする方法(作法)を知りたく質問しました。 少し現状を記しておきます。 現在goを使って、プログラムを書いています。 説明が分かりにくくなりますので、ここではmain.goとmypackage.goの2つファイルを作成している状況を仮定します。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を時間をかけずにコンパイルしているのでしょうか? ご教授をお願いします。
回答: 私の調べた限りでは、引数に巨大なオブジェクトを渡すとコンパイル時間が長くなります。 goはスタックフレームのガーベジコレクションに必要な情報を実行ファイル内に埋め込んでおり、引数のサイズが巨大になるとこのデータが肥大化します。 参考: `go tool 6g -S test.go`を実行してアセンブリを調べると、以下のようなデータが大量に埋め込まれていることが確認できます。このデータの出力がコンパイル時間に影響している可能性が高いと思います。 ``` 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 ... ``` 値ではなくポインタを渡すことでこの問題は解消できます。 ``` func Show(Img *ImgInfo) { } func main() { Img := ImgInfo{} Show(&Img) } ```