寝ても覚めてもこんぴうた

プログラム書いたり、ネットワーク設計したり、サーバ構築したり、車いじったり、ゲームしたり。そんなひとにわたしはなりたい。 投げ銭は kyash_id : chidakiyo マデ

# Go のテスト並列化してテストが速くなることを改めて確認してみた

f:id:chidakiyo:20200625164918j:plain

Go のテストに並列機能があるので、それで単純に速度アップができるのかという点と、 parallel オプションで並列数操作したらちゃんと反映されるよね。という点を確認した。

早速ソースコード

slow_test.go

func Test_slow1(t *testing.T) {
    time.Sleep(3 * time.Second)
}

func Test_slow2(t *testing.T) {
    time.Sleep(1 * time.Second)
}

func Test_slow3(t *testing.T) {
    time.Sleep(2 * time.Second)
}

fast_test.go

func Test_fast1(t *testing.T) {
    t.Parallel()
    time.Sleep(3 * time.Second)
}

func Test_fast2(t *testing.T) {
    t.Parallel()
    time.Sleep(1 * time.Second)
}

func Test_fast3(t *testing.T) {
    t.Parallel()
    time.Sleep(2 * time.Second)
}

見てわかるように fast の方ではテスト内で Parallel() を呼び出して並列処理を許可している。

早速実行

slow の方を実行する

% go test ./slow_test.go
ok      command-line-arguments  6.276s

6秒ちょい。
3 + 1 + 2 = 6秒なのでだいたい正しい。

fast の方を実行する

% go test ./fast_test.go
ok      command-line-arguments  3.729s

3.7秒。
3並列で実行され、一番遅い3秒のテスト時間+αという感じだろうか。

fast を並列数 1 で実行してみる

% go test -parallel 1 ./fast_test.go
ok      command-line-arguments  6.502s

6.5秒。 期待通り、並列化していない slow の結果とだいたい近い値になった。
Parallel() を呼び出していないものよりちょっと遅いのは Parallel() 呼び出しのオーバーヘッドがそこそこあるのだろうか。

fast を並列数 2 で実行してみる

% go test -parallel 2 ./fast_test.go
ok      command-line-arguments  3.342s

3.3秒。
3 : (1 + 2) で3秒少々で終わったという感じだろうか。

slow を並列数 3 で実行してみる

% go test -parallel 3 ./slow_test.go
ok      command-line-arguments  6.350s

6.3秒。
もちろんそうなるよね。という感じ。

まとめ

Go のテストは実行順序や、同時実行などを考慮しなくて良いテストに関しては Parallel() を実行し、並列化したほうがパフォーマンスが出る。
確認で使った環境は go1.14.3 で、このバージョンであれば、 go test コマンドに特に並列数など渡さなくてもテスト側で Parallel() を読んでいれば必要な数だけ並列化されそう。(もしくはPCのCore数に応じて?)

GitHub Actionsなどは時間課金なのでテスト高速化して削減できそう。

ではでは。