😊

📝 Go vs C# Todo App を Docker化して比較してみた!

に公開

はじめに

エンジニア4ヶ月目のSomeです!

前回、業務で使っているC#でTodoアプリを作ってDocker化してみました。

今回はGo言語とDockerを勉強中なので、同じ機能のTodoアプリをGoで作って、C#版と比較してみました!

結果が想像以上にすごかったので、共有します😊

🔧 環境

  • MacBook Air (M3)
  • メモリ: 16GB
  • Go: 1.21(勉強中)
  • .NET: 8.0(業務で使用)

**⚡ 結果まとめ - **

項目 C# Go
📦 イメージサイズ 379MB 11.5MB 33倍小さい!
🚀 処理速度 407 req/s 2,572 req/s 6倍速い!
⚡ 応答時間 24.56ms 2.3ms 10倍速い!
💾 メモリ使用量 52MB 22MB 半分以下!
📝 コード量 500行+ 150行 1/3!

正直、ここまで差が出るとは思ってませんでした...😅


🛠️ 作ったアプリ

機能

両方とも同じ機能を実装しました:

  • Todo追加: タイトル入力
  • Todo一覧: リスト表示
  • 完了切り替え: チェックボックス
  • Todo削除: 削除ボタン

C#版(前回作成)

ASP.NET Core Razor Pagesで作りました。

Models/Todo.cs              # データモデル
Data/TodoContext.cs         # データベース設定
Pages/Index.cshtml          # メインページ
Pages/Todos/Create.cshtml   # 作成ページ
Pages/Todos/Edit.cshtml     # 編集ページ
Pages/Todos/Delete.cshtml   # 削除ページ
Program.cs                  # メイン設定

合計: 15ファイル、500行くらい

Go版(今回作成)

Go初心者なので、あえてシンプルに標準ライブラリだけで作りました。

// main.go - これだけ!
package main

import (
    "html/template"
    "net/http"
    // など
)

type Todo struct {
    ID        int
    Title     string
    Completed bool
}

// CRUD関数 + HTTPハンドラー + HTMLテンプレート
// 全部で150行くらい

感想: Goの方がシンプルで分かりやすいかも!?


🐳 Docker化してみた

なぜDockerで比較?

  • 実際の環境に近い状態で測定したかった
  • メモリやCPUの使用量を正確に測りたかった
  • Dockerを覚えたばかりなので練習も兼ねて

C#のDockerfile

# マルチステージビルド
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -o out

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app/out .
# セキュリティ設定など...
ENTRYPOINT ["dotnet", "SimpleTodoAPI.dll"]

GoのDockerfile

# マルチステージビルド
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o main .

FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/main .
CMD ["./main"]

Docker初心者の感想: Goの方がDockerfileもシンプルでした!


📊 性能測定してみた

Apache Benchで測定

初めて使いましたが、Webサイトの性能測定の定番ツールらしいです。

基本テスト(同時接続10人)

# 1000回リクエスト、同時接続10人
ab -n 1000 -c 10 http://localhost:8080/

C#の結果

Time taken for tests:   2.456 seconds
Requests per second:    407.14 [#/sec]
Time per request:       24.56 [ms]

Goの結果

Time taken for tests:   0.529 seconds  ← C#の1/5!
Requests per second:    1890.23 [#/sec] ← C#の4.6倍!
Time per request:       5.290 [ms]     ← C#の1/5!

驚き: Goめちゃくちゃ速い...😳

高負荷テスト(同時接続100人)

# 10000回リクエスト、同時接続100人
ab -n 10000 -c 100 http://localhost:8080/

C#の結果

Time taken for tests:   24.56 seconds
Requests per second:    407.14 [#/sec]
Time per request:       245.6 [ms]    ← 10倍遅くなった

Goの結果

Time taken for tests:   3.888 seconds  ← C#の1/6!
Requests per second:    2572.10 [#/sec] ← C#の6.3倍!
Time per request:       38.879 [ms]    ← C#の1/6!

学び: 負荷が高くなってもGoは安定!

レスポンス時間の詳細

# 10回測定してみた
for i in {1..10}; do
  curl -o /dev/null -s -w "時間: %{time_total}s\n" http://localhost:8080/
done

Goの結果:

時間: 0.002787s (2.8ms)
時間: 0.001781s (1.8ms)
時間: 0.002051s (2.1ms)
...
平均: 2.3ms ← 超安定!

💾 メモリとCPUの使用量

測定方法

# Dockerコンテナのリソース使用量を確認
docker stats コンテナ名 --no-stream

結果比較

C#(前回測定)

# 普通の状態
CPU: 0.8% → 0.1%
メモリ: 52MB

# 負荷テスト中
CPU: 45.2%
メモリ: 67.3MB

Go(今回測定)

# 普通の状態
CPU: 0.00%  ← ほぼゼロ!
メモリ: 10MB

# 負荷テスト後
CPU: 0.00%
メモリ: 22MB ← C#の1/3

感想: Goのリソース効率すごすぎる...


🤔 なぜこんなに差が出るの?

Go初心者なりに調べてみました:

C#の特徴

  • .NET Runtimeが必要(重い)
  • 多機能で便利だけど、その分重い
  • JIT(Just-In-Time)コンパイル

Goの特徴

  • 実行ファイル1つで動く(軽い)
  • シンプルで必要最小限
  • 事前にコンパイル済み

初心者の理解: C#は高機能だけど重い、Goはシンプルだけど軽くて速い


💰 実際のコストへの影響

イメージサイズの差

C#: 379MB
Go: 11.5MB

差: 33倍!

これって、クラウドで動かすときの転送コストに直結しますよね...

簡単な計算

月100回デプロイする場合:

C#: 379MB × 100回 = 37.9GB
Go: 11.5MB × 100回 = 1.15GB

転送量: 97%削減!

サーバーコスト

同じサーバーで動かす場合:

C#: 1台で407 req/s
Go: 1台で2,572 req/s

→ Goなら6分の1のサーバー台数で済む

学び: 性能差は直接お金に影響する!


😅 正直な感想

予想していたこと

  • Goの方が少し速いかな?
  • イメージサイズも少し小さいかな?

実際の結果

  • 6倍速い ← 予想外
  • 33倍小さい ← 嘘だろ...
  • メモリ半分以下 ← すごすぎ

学習した教訓

  1. 言語の選択って大事: 用途に応じて選ぶべき
  2. Docker化すると違いがはっきり: 実測って重要
  3. シンプルの威力: 複雑 ≠ 良い

🤷‍♂️ どっちを使えばいいの?

初心者なりの判断基準:

Goを選ぶ場面

  • API作る時: 速くて軽い
  • クラウドで動かす時: コスト削減
  • シンプルなWebアプリ: 学習コストも低い

C#を選ぶ場面

  • 複雑な業務システム: 豊富な機能
  • チーム開発: ツールが充実
  • Windows環境: やっぱり相性良い

個人的な感想

  • 学習用: Goの方が分かりやすい
  • 業務用: C#の方が安心(今のところ)
  • 趣味: Goが楽しい!w

📝 実際に実行したコマンド

# Docker化
docker build -t go-todo-app .
docker run -d -p 8080:8080 --name go-todo-app go-todo-app

# 性能測定
ab -n 1000 -c 10 http://localhost:8080/
ab -n 10000 -c 100 http://localhost:8080/

# レスポンス時間測定
for i in {1..10}; do
  curl -o /dev/null -s -w "時間: %{time_total}s\n" http://localhost:8080/
done

# リソース確認
docker stats go-todo-app --no-stream

# イメージサイズ確認
docker images | grep todo

🚀 次にやってみたいこと

  1. データベース接続: PostgreSQLを使った場合の比較
  2. 認証機能: JWT認証の実装と性能比較
  3. フレームワーク比較: GinやEchoを使った場合
  4. 本格的な監視: PrometheusとGrafanaでメトリクス収集

📚 参考にした資料


💭 まとめ

率直な感想: ここまで差が出るとは思いませんでした!

今回の発見:

  • Goの性能は本当にすごい(33倍、6倍、10倍...)
  • Dockerで測定すると違いがはっきり分かる
  • 言語選択は性能とコストに直結する

学んだこと:

  • 実際に測定することの大切さ
  • 適材適所で言語を選ぶ重要性
  • シンプルな実装の威力

次のステップ:
Go の勉強をもっと頑張って、実際の開発でも使えるようになりたいです!

4ヶ月目エンジニアの正直な感想: C#も好きだけど、Goも面白い!
適材適所で使い分けられるエンジニアになりたいです😊


読んでくださってありがとうございました!
同じような初心者の方の参考になれば嬉しいです 🙌

Discussion