LoginSignup
6
3

More than 5 years have passed since last update.

Go言語で並列処理

Posted at

Go言語で並列処理

Go言語でサーバのパフォーマンスを向上させる!というタスクがあったとします。その場合、シングルスレッドで直列的に処理をしていてはパフォーマンスは大きく下がってしまうと思います。そこで並列処理の登場です!

並列処理とは

マルチスレッドで複数の処理を同時に処理することです。例えば、あるスレッドではループ処理をして、もう一方のスレッドではデータベースアクセスをする等同時に処理することで処理のスピードは大幅に変わります。

実験

実際に実装してみて処理時間に差が出るが見てみましょう。なお処理時間の差がわかりやすくなるように1千万回ループしています。

直列処理

まずはシングルスレッドでの直列的な処理です。

package main

import (
    "fmt"
    "time"
)

func loop(id int) {
  for i := 0; i < 10000000; i++ {
  }
}

func main() {
  start := time.Now()
  loop(1)
  loop(2)
  loop(3)
  end := time.Now()
  fmt.Printf("%f秒\n", (end.Sub(start)).Seconds())
}

結果は以下のようになりました。

$ go run main.go
0.017746秒

これだけみてもよくわからないので次に並列処理です。

並列処理

go言語にはGoroutineというものがあり、関数名の前にgoをつけるだけで並列処理になります。また、channelというものもありデータの送受信などが出来るみたいですが今回は返り値がないので適当にbooleanを返しておきます。実装は以下のようになります。

package main

import (
    "fmt"
    "time"
)

func loopByParallel(id int, ch chan bool) {
  for i := 0; i < 10000000; i++ {
  }
  ch <- true
}

func main() {
  start := time.Now()
  ch1 := make(chan bool)
  ch2 := make(chan bool)
  ch3 := make(chan bool)
  go loopByParallel(1, ch1)
  go loopByParallel(2, ch2)
  go loopByParallel(3, ch3)
  <-ch1
  <-ch2
  <-ch3
  end := time.Now()
  fmt.Printf("%f秒\n", (end.Sub(start)).Seconds())
}

これで3つのループ処理が並列に処理されるはずです。結果を見てみましょう。

$ go run main.go
0.007073秒

見事に実行時間が2/5程度になりました!

まとめ

いかがだったでしょうか?今度はchannelの正しい使い方やWebサーバへの応用なども見ていきたいところです!それでは

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3