🎯 TL;DR(結論先出し)
Go圧勝! でも、Rustも意外な健闘を見せました👀
🏆順位 | 言語 | 実行時間 | CPU効率 | 一言コメント |
---|---|---|---|---|
🥇 | Go | 0.653秒 | 最高 | やっぱりネットワーク処理最強 |
🥈 | Rust | 1.109秒 | 良好 | CPU効率は優秀だけど... |
🥉 | Python | 1.318秒 | 普通 | 開発速度で勝負! |
🤔 なぜこの検証をやったのか
クラウドエンジニアやってると、みんな一度は悩むじゃないですか?
「結局どの言語が一番速いの?」
特に最近は、
- 「Rustが最速らしい」
- 「いやGoの方が実用的」
- 「Pythonは遅いけど開発が楽」
みたいな話をよく聞くので、実際に同じ処理を3言語で書いて測ってみました!
⚙️ 検証内容
測定対象
AWS EC2の DescribeSecurityGroups API を呼び出して、セキュリティグループ一覧を取得する処理
なぜこの処理?
- 現実的: 実際のAWS運用でよく使う
- ネットワークI/O中心: 言語の特性が出やすい
- シンプル: 実装の複雑さによる影響を排除
測定環境
- OS: macOS
- リージョン: ap-northeast-1(東京)
-
測定方法:
time
コマンド - 重要: 事前コンパイル済みで測定(コンパイル時間除外)
💻 実装コード
Go実装(一番シンプル!)
package main
import (
"context"
"fmt"
"log"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/ec2/types"
)
func main() {
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
log.Fatalf("設定読み込みエラー: %v", err)
}
client := ec2.NewFromConfig(cfg)
if err := describeSecurityGroups(client); err != nil {
log.Fatalf("API呼び出しエラー: %v", err)
}
}
func describeSecurityGroups(client *ec2.Client) error {
output, err := client.DescribeSecurityGroups(context.TODO(), &ec2.DescribeSecurityGroupsInput{})
if err != nil {
return fmt.Errorf("API失敗: %w", err)
}
for _, group := range output.SecurityGroups {
printSecurityGroup(group)
}
return nil
}
func printSecurityGroup(group types.SecurityGroup) {
groupName := getStringValue(group.GroupName)
groupID := getStringValue(group.GroupId)
vpcID := getStringValue(group.VpcId)
description := getStringValue(group.Description)
fmt.Printf("セキュリティグループ: %s (%s), VPC: %s, 説明: %s\n",
groupName, groupID, vpcID, description)
}
// nil安全なヘルパー関数
func getStringValue(s *string) string {
if s == nil {
return "unknown"
}
return *s
}
Rust実装(型安全!)
use aws_sdk_ec2;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = aws_config::load_from_env().await;
let client = aws_sdk_ec2::Client::new(&config);
describe_security_groups(&client, vec![]).await;
Ok(())
}
async fn describe_security_groups(client: &aws_sdk_ec2::Client, group_ids: Vec<String>) {
let response = client
.describe_security_groups()
.set_group_ids(if group_ids.is_empty() { None } else { Some(group_ids) })
.send()
.await;
match response {
Ok(output) => {
for group in output.security_groups() {
println!(
"セキュリティグループ: {} ({}), VPC: {}, 説明: {}",
group.group_name().unwrap_or("unknown"),
group.group_id().unwrap_or("id-unknown"),
group.vpc_id().unwrap_or("vpcid-unknown"),
group.description().unwrap_or("(none)")
);
}
}
Err(err) => {
eprintln!("エラー: {:?}", err);
}
}
}
Python実装(お馴染み!)
import boto3
def describe_security_groups():
ec2 = boto3.client('ec2')
try:
response = ec2.describe_security_groups()
for group in response['SecurityGroups']:
print(f"セキュリティグループ: {group['GroupName']}, "
f"VPC: {group.get('VpcId', 'unknown')}, "
f"説明: {group.get('Description', 'none')}")
except Exception as e:
print(f"エラー: {e}")
if __name__ == "__main__":
describe_security_groups()
📊 測定結果発表!
実行結果(生ログ)
# 🥇 Go(爆速!)
$ time ./main
セキュリティグループ: default (sg-056e444c1891b25f7), VPC: vpc-0c896a4cf4a0ea47e, 説明: default VPC security group
セキュリティグループ: launch-wizard-1 (sg-0aa114dbcfa7f4094), VPC: vpc-0c896a4cf4a0ea47e, 説明: launch-wizard-1 created 2025-06-23T19:28:45.143Z
セキュリティグループ: launch-wizard-2 (sg-09e4b82ddc89e99a7), VPC: vpc-0c896a4cf4a0ea47e, 説明: launch-wizard-2 created 2025-06-23T19:39:03.390Z
./main 0.01s user 0.01s system 4% cpu 0.653 total
# 🥈 Rust(健闘)
$ time ./target/release/aws-operations
セキュリティグループ: default (sg-056e444c1891b25f7), VPC: vpc-0c896a4cf4a0ea47e, 説明: default VPC security group
セキュリティグループ: launch-wizard-1 (sg-0aa114dbcfa7f4094), VPC: vpc-0c896a4cf4a0ea47e, 説明: launch-wizard-1 created 2025-06-23T19:28:45.143Z
セキュリティグループ: launch-wizard-2 (sg-09e4b82ddc89e99a7), VPC: vpc-0c896a4cf4a0ea47e, 説明: launch-wizard-2 created 2025-06-23T19:39:03.390Z
./target/release/aws-operations 0.18s user 0.03s system 18% cpu 1.109 total
# 🥉 Python(まずまず)
$ time python describe_security_groups.py
セキュリティグループ: default, VPC: vpc-0c896a4cf4a0ea47e, 説明: default VPC security group
セキュリティグループ: launch-wizard-1, VPC: vpc-0c896a4cf4a0ea47e, 説明: launch-wizard-1 created 2025-06-23T19:28:45.143Z
セキュリティグループ: launch-wizard-2, VPC: vpc-0c896a4cf4a0ea47e, 説明: launch-wizard-2 created 2025-06-23T19:39:03.390Z
python describe_security_groups.py 0.55s user 0.19s system 56% cpu 1.318 total
📈 結果まとめ
言語 | 実行時間 | CPU時間 | CPU使用率 | 評価 |
---|---|---|---|---|
Go | 0.653秒 | 0.02秒 | 4% | 🚀 最速 |
Rust | 1.109秒 | 0.21秒 | 18% | ⚡ CPU効率良し |
Python | 1.318秒 | 0.74秒 | 56% | 🐍 安定感 |
🧐 time
コマンドの読み方(重要!)
ここ、めっちゃ重要なんで説明します!
./main 0.01s user 0.01s system 4% cpu 0.653 total
- user: プログラムがCPU使った時間
- system: システムコール(ネットワーク等)の時間
- total: 👈これが実際の待ち時間!
- cpu: CPU使用率
つまり、Rustは...
- CPU処理時間: 0.21秒(優秀✨)
- 実際の待ち時間: 1.109秒(あれ?🤔)
- 差分0.89秒 = ネットワーク待機時間
🔍 なぜこの結果になったのか?
🏆 Goが最速な理由
-
ネットワーク処理に特化した設計
-
net/http
が超最適化されてる - ゴルーチンでI/O待機が効率的
-
-
軽量なガベージコレクション
- 短時間実行ではGCほぼ影響なし
- メモリ使用も効率的
-
成熟したAWS SDK
- HTTPクライアントが完成度高い
- JSON処理も最適化済み
🤔 Rustが意外にもGoより遅い理由
でも待って!RustのCPU効率は良い!
実は、Rustは:
- CPU処理: 0.21秒(Goの0.02秒より遅いが効率的)
- I/O待機: 0.89秒(ここで時間かかってる)
理由:
-
Tokio非同期ランタイムのオーバーヘッド
- 単純なHTTP req/resには重い
- イベントループ初期化コスト
-
AWS SDK for Rustがまだ新しい
- 2021年以降のSDK
- HTTPクライアント最適化が発展途上
-
型安全性とのトレードオフ
- コンパイル時最適化はCPU処理メイン
- I/O処理では型チェックのオーバーヘッド
🐍 Pythonについて
- boto3の多くがC拡張なので健闘
- でもやっぱりインタープリター言語の限界
💡 実務での使い分け指針
この結果を踏まえて、実際の開発でどう選ぶべきか:
🚀 AWS CLI/ツール開発 → Go一択
✅ 最速実行
✅ シングルバイナリ配布
✅ クロスプラットフォーム
✅ 学習コストも低め
🛠️ システムプログラミング → 用途で判断
# CPU集約的(計算、画像処理等)
→ Rust 🦀
# ネットワーク集約的(API、マイクロサービス)
→ Go 🐹
# メモリ安全性重視
→ Rust 🦀
🐍 プロトタイピング/スクリプト → Python
✅ 爆速開発
✅ 豊富なライブラリ
✅ データ分析にも使える
🌐 Webアプリ/マイクロサービス → Go
✅ 高スループット
✅ 低レイテンシ
✅ Dockerとの親和性
✅ k8sでも軽い
🎁 おまけ:コンパイル時間込みだとどうなる?
参考までに、初回実行(コンパイル時間込み)の結果:
言語 | 初回実行 | 備考 |
---|---|---|
Python | 1.318秒 | コンパイル不要で最速 |
Go | 2.934秒 |
go run でコンパイル |
Rust | 8.887秒 |
cargo run 重い😅 |
ワンショットスクリプトならPython最強説
🔄 検証を再現したい方へ
1. 環境準備
# Go
go mod init aws-test
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/service/ec2
# Rust
cargo new aws-test
# Cargo.tomlに依存関係追加
# Python
pip install boto3
2. 事前コンパイル
# Go
go build -o main main.go
# Rust
cargo build --release
# Python(不要)
3. 測定
# 各言語で実行
time ./main
time ./target/release/aws-test
time python script.py
# 複数回測定推奨
for i in {1..3}; do echo "実行 $i:"; time ./main; echo; done
🎯 まとめ
今回の大発見 🔍
-
「Rust最速神話」は用途次第
- CPU処理: Rust有利
- ネットワーク処理: Go有利
-
timeコマンドちゃんと読もう
-
total
時間 = ユーザー体感 -
user+system
時間 = プログラム効率
-
-
エコシステム成熟度めっちゃ重要
- 言語性能 < SDK最適化
- 特にI/O処理では顕著
-
実測大事!
- 理論値 ≠ 実測値
- 自分の用途で測るべし
🎖️ 最終判定
AWS運用・ツール開発なら Go がおすすめ!
でも、用途によってはRustやPythonも全然アリ。
大事なのは、目的に応じて適切に選択することですね 💪
💬 他のAWSサービスでも測ってみたい!コメントで教えて!
🔄 次はS3操作とかLambdaの比較もやってみたいと思います!
参考リンク