前回の記事では、
Why my Go program is slow?(@methane氏)
このセッションでは、pprof
というCPUプロファイラとGo言語におけるパフォーマンスチューニングについての話がされました。なお、
サンプリングプロファイラ
pprof
はサンプリングプロファイラで、
用途に適したパッケージを使う
同氏は、runtime/
を直接使用するのではなく、net/
を使用すると良いと主張していました。なお、net/
は以下のようにimport
するだけで使えるそうです。
また同氏は、davecheney/
を使うと良いと述べていました。
Macでサンプリングプロファイラを使用するためには
pprof
はSIGPROF
というシグナルを送る機能を利用しているそうですが、pprof
を利用できないそうです。この件の詳細は、pprof
できるようにしているそうです。なお、
methane氏は、
go tool pprof
runtime/
およびnet/
でプロファイリングした結果は、go tool pprof
を使って解析することができるそうです。元々このツールは、perftools
を利用していたそうですが、go tool pprof
を使うことを同氏は推奨していました。このセッションでは、pprof
を使ってプロファイリングをするデモが行われました。pprof
の使い方については、
- http://
blog. golang. org/ profiling-go-programs - https://
software. intel. com/ en-us/ blogs/ 2014/ 05/ 10/ debugging-performance-issues-in-go-programs
Go言語で書かれたプログラムが遅くなる理由
同氏は、
- ガベージコレクション
(GC) - メモリコピー
- 関数呼び出し
ガベージコレクション(GC)
GCが重い場合は、GODEBUG=gctrace=1
というデバッグフラグを付けるとGCの情報が見られるそうです。また、pprof
のヒープのプロファイラを使うと、sync.
を使ってオブジェクトをプールしておき、
また、make
関数で指定すると、GOGC
という環境変数の値を大きくすることで、
なお、
メモリコピー
string
型で持っている値を実際に使う際に頻繁に[]byte
型に変換
する場合、[]byte
型で値を持つと良いと述べていました。また、net/
パッケージのReader.
で行われているテクニックについての説明がされていました。
なお、Reader.
については同氏の記事で詳しく解説されています。
関数呼び出し
同氏は以下の理由により、
- 引数や戻り値がレジスタではなくスタック渡しであるため
- 呼び出す側が使用しているすべてのレジスタを退避させる必要があるため
- 関数呼び出し時にゴルーチンの切り替えやGCのストップザワールドのために起こるランタイムのフックがあるため
一方で、
Golang JP Community (@qt_luigi氏 )
このセッションでは、
Golang JP Community(Google+)
まずはじめに、
日本各地の勉強会
つぎに2014年に日本各地で行われたGo言語の勉強会について紹介されていました。2014年にはおよそ140の勉強会が日本各地で行われたそうです。その中でも、
関東
- Go Conference:毎年春と秋に行われる日本最大のGo言語のカンファレンス
- タネマキGAE:Google App Engine for GoとPythonについての勉強会
- Tokyo Golang Developers:日本に住む外国人が中心になって行っているイベント
- 質実Go研:主にGo言語の標準パッケージのコードリーディングや参加者でさまざまな課題の実装方法模索するイベント
- Go弱の会:初心者向けのイベント
- 大井町Go:大井町で行われている勉強会
- Gunosy.
go :株式会社Gunosyで行われる勉強会 - ヒカルのGo:株式会社ディー・
エヌ・ エー (ヒカリエ) で行われる勉強会 - dwanGo:株式会社ドワンゴで行われる勉強会
その他の地域
- Shizuoka.
go :静岡で行われる勉強会 - Golang Cafe:GDGChugoku主催の勉強会でGo言語の勉強会では開催数は最多
- Fukuoka.
go :福岡で行われる勉強会
インターネット上の情報源
さいごにGo言語に関するインターネット上の情報源について紹介がされていました。
- golang-jp:golang.
org を日本語に翻訳しているサイト - Golang Samples:サンプルコードをまとめているGitHubのOrganization
- Lingr
(Go言語) :Go言語について議論や質問をやりとりするためのチャット - Qiita
(Goタグ) :Go言語の記事がまとめてあるQiitaのタグ - Go Advent Calendar 2014:Go言語の2014年のアドベントカレンダー
NSQ-Centric Architecture(Greg氏)
このセッションでは、
NSQ
NSQとは、
- チャットサーバを作る
- リアルタイム
- スケールしやすい
- 分散
- 柔軟でシンプルに設定できる
- Go言語で書きたい
- アプリ内Webviewで使うためWebsocketを利用
- ロードバランスさせたい
同氏はNSQの特徴として以下の点を挙げていました。
- 単一障害点
(SPOF) がない分散システム - 横にスケールしやすい
- レイテンシーが低く、
プッシュでメッセージを送る - ロードバラスもマルチキャストもできる
- データフォーマットは何でも利用できる
また、
- デフォルトでは永続化されない
- メッセージは必ず1回以上届く
- メッセージが届く順序は決まっていない
- コンシューマは少し時間がかかっても最終的には全部のトピックを見つける
なお、--mem-queue-size=0
というオプションを付けると良いと同氏は述べていました。
NSQにはトピック、
WebviewでiMessage風なアプリを作る
プロトコル
同氏はNSQを使って、
- シンプルなJSON
- サーバ同士とサーバ・
クライアントのやりとりが同じ形式 - ルーティングしやすい
最終的に、
チャネル
同氏はいくつかの用途によって以下のチャネルを作成したそうです。
- Websocketチャネル
- アーカイブチャネル
- プッシュチャネル
- マイクロサービス
Websocketチャネルは以下のように実装したそうです。
- Websocketサーバ1台につき1チャネル
- すべてのメッセージがすべてのサーバに届くため、
宛先を見て関係無いものは無視をする - ネットワーク障害があった場合はNSQがメッセージを保管する
- 分散
(少なくともマルチプレックス) チャットになる
また、
- 1つのチャネルに複数のコンシューマ
- すべてのメッセージを受取り、
DBに書き込む - ロードバランスを実現するためには、
単にサーバを足せばよい - アーカイブプロセスとDBを同じサーバにすれば直接メッセージをDBに送ることができる
プッシュチャネルは以下のように実装したそうです。
- 1つのチャネルに1つのコンシューマ
- チャットメッセージと既読メッセージを受け取って、
未読数を数える - 「新着メッセージが◯件あります。」
というプッシュ通知を送る
現在はプッシュサーバが1台であるそうですが、
NSQを利用して開発したシステムでは、
クライアントサイド
同氏は、
- メッセージが届く順番が決まっていない
- メッセージは2回以上届く可能性がある
同氏はメッセージは、
Hacking Go Compiler Internals(moriyoshi氏)
このセッションでは、
Go言語のコンパイラの構造
まずはじめにGo言語のコンパイラの簡単な説明がされました。同氏はGo言語のコンパイラは以下のような順序で処理を行っていると説明していました。
字句解析におけるハック
字句解析器では、src/
を読むと、
構文解析におけるハック
構文解析器は、
同氏は、
上記のようにインデクサのオーバライドができるように、
- 抽象構文木に新しいノードタイプ
( OINDEXINTER
)を追加 typecheck
という抽象構文木に型情報を埋め込むフェーズで、通常インデクサが有効な型 (文字列、 配列、 スライス、 マップ) 以外の場合に OINDEXINTER
を処理する部分を追加walk
というフェーズで、OINDEXINTER
のノードを関数呼び出しのノードに変換し、再度その部分に typecheck
とwalk
を施すという処理を行う- 評価順序を修正する部分で
OINDEXINTER
を処理するコードを追加する
同氏はセッションの最後に、print
関数がノードや型の情報を出力する書式を提供しているためハックする際に大変便利だったと述べていました。
How we use Go(@ironzeb氏)
このセッションでは、
Gengoでは、
なお、
まとめ
Go Conference 2014 Autumnについて、
2014年は、
2015年はさらにGo言語を採用する場面が増えていき、
つぎのGo Conference 2015 Spring