Go言語は、Googleによって設計された「シンプルで高速なプログラミング言語」として広く知られています。特にGoの並列処理の簡潔さと高性能は、多くの開発者にとって魅力的です。
今回は、Go言語で並列処理を実装し、他の言語(C言語、Python、Java、Ruby)と比較した結果を共有します。Goが「なぜ選ばれるのか」を、実際のコードとともに掘り下げていきます。
テスト仕様
テスト環境の仕様
- CPU: 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
- RAM: 32.0 GB
- OS: Windows 11 Pro 64ビット
使用言語とバージョン
- Go 1.23.4
- Java 21.0.5
- Python 3.11.7(GIL有効。並列処理)
- Python 3.13.1t (GIL無効。並列処理)
- Ruby 3.3.6
- C言語:GCC 14.2.0
準備した各ソースコード
Go言語での並列処理プログラム
以下は、Goで10万回のトランザクションを並列処理するプログラムの例です。
プログラムコード
package main
import (
"fmt"
"sync"
"time"
)
func processTransaction(id int) {
// 模擬トランザクション処理
_ = id * 2
}
func main() {
var wg sync.WaitGroup
start := time.Now()
transactionCount := 100000
wg.Add(transactionCount)
for i := 0; i < transactionCount; i++ {
go func(id int) {
defer wg.Done()
processTransaction(id)
}(i)
}
wg.Wait()
fmt.Printf("Completed %d transactions in %v\n", transactionCount, time.Since(start))
}
コードの解説
- goroutineを利用した並列処理
go
キーワードを使うだけで、並列タスクを簡単に作成可能。- goroutineは軽量で、数百万単位でも効率的に動作します。
sync.WaitGroup
によるタスクの同期sync.WaitGroup
を使い、すべてのgoroutineが完了するまでメインスレッドを待機。- 並列処理の終了を簡単に管理できます。
- 時間計測
time.Now()
で開始時刻を記録し、time.Since(start)
で実行時間を算出。
- シンプルな構文
- スレッドやメモリ管理を意識する必要がなく、短いコードで実装可能。
Go言語の強み
- 軽量な並列処理
- goroutineはOSスレッドよりも軽量で、高速かつ低メモリで動作。
- Goランタイムがスレッドのスケジューリングを自動で管理。
- 簡潔なコード
- 並列処理を記述するのに必要なのは
go
キーワードと同期用のWaitGroup
。 - 他の言語に比べ、圧倒的にシンプル。
- 並列処理を記述するのに必要なのは
- 高いパフォーマンス
- Goはコンパイル型言語で、バイナリファイルを直接実行。
- goroutineとGoランタイムによる最適化がパフォーマンスを向上させます。
言語 | 実行時間 | 特徴 |
---|---|---|
Go1.23.4 | 33.4ms | goroutineによる軽量かつ高速な並列処理 |
Java 20.0.5 | 60.7ms | 固定スレッド数で効率的な並列処理を実現。 |
Python 3.11.7 | 1.1秒 | GILの恩恵を受けている。 |
Python 3.13.1 | 1.4秒 | GIL無効化した場合、期待が外れてオーバーヘッドが大きくなった可能性が大きい。 |
C 言語14.2.0 | 4.4秒 | C言語は思ったより遅い結果に。 |
Ruby3.3.6 | 57.8秒 | スレッドのオーバーヘッドが大きい。 |
なぜGo言語が選ばれるのか?
- 開発効率
- goroutineと
WaitGroup
を使った並列処理は、他言語に比べて非常に簡潔で直感的。 - コードの可読性が高く、保守が容易。
- goroutineと
- パフォーマンス
- Goのランタイムがgoroutineを効率的にスケジュール。
- 高速なコンパイルと軽量な実行バイナリにより、性能を最大限に引き出します。
- 適用分野
- Webサーバー、マイクロサービス、リアルタイムシステムなど、大量の並列処理が必要な場面で特に強い。
他言語の課題
Java
- スレッドプールは強力だが、スレッドのオーバーヘッドがGoに比べて大きい。
C言語
- 最速だが、コードが複雑で開発・保守の負担が大きい。
- メモリ管理やスレッド制御を手動で行う必要がある。
Python
- GIL(Global Interpreter Lock)の影響で、CPUバウンド処理は遅い。
- I/Oバウンド処理では効果的。
- GILが処理性能の足かせになる場面を想定し、Python 3.13.1でGILを無効化して並列処理を試しました。しかし、今回の処理内容(比較的単純なトランザクション計算)では、GIL有効時の方が効率的に動作しました。期待通りの結果にはなりませんでしたが、GILが必ずしも性能を妨げるわけではない点が確認できました。
Ruby
- スレッドのオーバーヘッドが大きく、GILにより並列性能が制限される。
まとめ
Go言語は、簡潔さ、高速性、スケーラビリティを兼ね備えたプログラミング言語です。特に並列処理においては、goroutineとランタイムの最適化により、非常に効率的な実装が可能です。
Goを選ぶべき場面
- 並列処理が大量に発生するシステム(Webサーバー、リアルタイム処理など)。
- 高いパフォーマンスが求められる場面。
- 短い開発期間で保守性の高いコードが求められる場合。
Go言語は「並列処理のエース」として活躍すること間違いなし!ぜひ実際にコードを書いて体感してみてください!
コメントを残す