こんにちは。Tomoyuki(@tomoyuki65)です。
Go言語(Golang)ではgoroutine(ゴールーチン)を使うことによって並行処理が可能なため、上手く使えばパフォーマンス改善に繋がります!
※プログラムは通常一行ずつ処理をしていきますが、並行処理をすれば複数の処理を一度に同時に実行できます。
Go言語(Golang)はgoroutine(ゴールーチン)で並行処理が可能!
まずは以下のプログラムを実行してみて下さい。
package main
import (
"fmt"
"time"
)
func wait50ms() {
time.Sleep(time.Millisecond * 50)
}
func wait100ms() {
time.Sleep(time.Millisecond * 100)
}
func main() {
elapsedTime := time.Now()
// 二つの関数を実行
wait50ms()
wait100ms()
fmt.Println("経過時間: ", time.Since(elapsedTime))
}
実行結果は以下のようになります。
経過時間: 150ms
次に上記で実行した二つの関数をgoroutine(ゴールーチン)を使って実行する場合、以下のように修正します。
package main
import (
"fmt"
"time"
)
func wait50ms() {
time.Sleep(time.Millisecond * 50)
}
func wait100ms() {
time.Sleep(time.Millisecond * 100)
}
func main() {
elapsedTime := time.Now()
// 二つの関数をgoroutineで並行実行
go wait50ms()
go wait100ms()
fmt.Println("経過時間: ", time.Since(elapsedTime))
}
実行結果は以下のようになります。
経過時間: 0s
このようにgoroutineで並行実行をした場合、処理の完了を待たなくなるため、すぐに一番最後の処理である「fmt.Println(“経過時間: “, time.Since(elapsedTime))」が実行して処理が完了してしまいます。
このままだと不都合に処理が終了してしまうので、goroutineで並行実行した処理の完了を待ってから次の処理をさせたい場合は、標準ライブラリ「sync」を使います。
package main
import (
"fmt"
"time"
"sync"
)
func wait50ms(wg *sync.WaitGroup) {
time.Sleep(time.Millisecond * 50)
// 定義したWaitGroupを一つ完了させる
wg.Done()
}
func wait100ms(wg *sync.WaitGroup) {
time.Sleep(time.Millisecond * 100)
// 定義したWaitGroupを一つ完了させる
wg.Done()
}
func main() {
elapsedTime := time.Now()
// WaitGroupを二つ定義
var wg sync.WaitGroup
wg.Add(2)
// 二つの関数をgoroutineで並行実行
go wait50ms(&wg)
go wait100ms(&wg)
// 二つのWaitGroupが完了するまで待つ
wg.Wait()
fmt.Println("経過時間: ", time.Since(elapsedTime))
}
実行結果は以下のようになります。
経過時間: 100ms
このようにgoroutineとsyncを使うことで並行処理を実現でき、経過時間も最初と比べて50ms短縮できました!
最後に
今回はgoroutine(ゴールーチン)による並行処理についてご紹介しました。
Go言語でパフォーマンスを考慮する場合はこの並行処理を使うことを検討する必要があり、実務では大事な機能になると思うので、ぜひ基本的な使い方を覚えておきましょう。
コメント