18
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Go言語】フレームワーク8種のベンチマークを測定してみた

Posted at

はじめに

Gin, Fiber, Echo, Iris, Aero, Gorilla, Chi, Beegoの8つのフレームワーク(Gorilla等は厳密にいうとフレームワークではない)のパフォーマンスを比較してみました。

BombardierというGo製のツールを用いて、ベンチマークを測定しました。結果だけ知りたい人は 結果 まで飛んでください。

テスト環境情報

MacBook Air M2
メモリ 16GB
macOS 13.6
Docker Compose version v2.23.0-desktop.1
Docker version 24.0.6
go version 1.21.5
gin v1.9.1
Fiber v2.52.0
Echo v4.11.4
Iris v12.2.8
Aero v1.3.59
Gorilla v1.8.1
Chi v1.5.5
Beego v2.1.4

テスト対象サーバのコード

Gin

main.go
package main

import "github.com/gin-gonic/gin"

func main() {
	gin.SetMode(gin.ReleaseMode)
	r := gin.New()
	r.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "hello",
		})
	})
	r.Run()
}

Fiber

main.go
package main

import "github.com/gofiber/fiber/v2"

func main() {
	app := fiber.New()

	app.Get("/", func(c *fiber.Ctx) error {
		return c.JSON(fiber.Map{
			"message": "hello",
		})
	})

	app.Listen(":8080")
}

Echo

main.go
package main

import (
	"github.com/labstack/echo/v4"
	"net/http"
)

func main() {
	e := echo.New()

	e.GET("/", func(c echo.Context) error {
		return c.JSON(http.StatusOK, map[string]string{"message": "hello"})
	})

	e.Start(":8080")
}

iris

main.go
package main

import "github.com/kataras/iris/v12"

func main() {
	app := iris.New()
	app.Get("/", func(ctx iris.Context) {
		ctx.JSON(iris.Map{
			"message": "hello",
		})
	})

	app.Run(iris.Addr(":8080"))
}

Aero

main.go
package main

import (
	"github.com/aerogo/aero"
)

func main() {

	app := aero.New()
	app.Config.Ports.HTTP = 8080

	app.Get("/hello", func(ctx aero.Context) error {
		return ctx.JSON(map[string]interface{}{
			"message": "hello",
		})
	})

	app.Run()
}

Gorilla

main.go
package main

import (
	"encoding/json"
	"net/http"

	"github.com/gorilla/mux"
)

func main() {
	router := mux.NewRouter()

	router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)

		response := map[string]string{"message": "hello"}
		json.NewEncoder(w).Encode(response)
	}).Methods("GET")

	http.Handle("/", router)

	// ポート8080でサーバーを起動
	http.ListenAndServe(":8080", nil)
}

Chi

main.go
package main

import (
	"encoding/json"
	"net/http"

	"github.com/go-chi/chi"
)

func main() {
	r := chi.NewRouter()

	r.Get("/", func(w http.ResponseWriter, r *http.Request) {
		response := map[string]string{"message": "hello"}
		json.NewEncoder(w).Encode(response)
	})

	http.ListenAndServe(":8080", r)
}

beego

main.go
package main

import (
	"github.com/beego/beego/v2/server/web"
)

type MainController struct {
	web.Controller
}

func (ctrl *MainController) Get() {
	ctrl.Data["json"] = map[string]string{"message": "hello"}
	ctrl.ServeJSON()
}

func main() {
	web.Router("/", &MainController{})
	web.Run()
}

テストケース

以下の4つのケースで行いました。

# 1コネクションで合計1000000リクエスト送る
bombardier -c 1 -n 1000000 http://localhost:8080
# 1コネクションで10秒間リクエストする
bombardier -c 1 -d 10s -l http://localhost:8080
# 200コネクションで1000000リクエスト送る
bombardier -c 125 -n 1000000 http://localhost:8080
# 125コネクションで10秒間リクエストする
bombardier -c 200 -d 10s -l http://localhost:8080

結果

1コネクションで1000000リクエスト送った結果

フレームワーク Reqs/sec(Avg) Reqs/sec(Stdev) Reqs/sec(Max) Latency(Avg) Latency(Stdev) Latency(Max) Throughput
Gin 17243.16 1907.85 49741.92 56.73us 35.67us 11.73ms 3.36MB/s
Fiber 20517.75 1812.56 61718.28 47.52us 23.76us 10.21ms 3.70MB/s
Echo 17212.66 1587.81 41085.46 56.81us 44.09us 14.58ms 3.37MB/s
iris 16554.60 1296.85 31794.50 59.14us 29.66us 18.43ms 3.24MB/s
Aero 17517.70 2971.88 55515.81 55.82us 72.92us 23.27ms 2.40MB/s
Gorilla 16653.57 2559.59 37527.32 58.80us 64.68us 23.68ms 3.02MB/s
Chi 17084.79 2018.57 42708.64 57.26us 58.04us 17.75ms 3.24MB/s
beego 15426.07 2108.86 34108.83 63.51us 57.57us 20.79ms 3.00MB/s

single1.png

1コネクションで10秒間リクエストした結果

フレームワーク Reqs/sec(Avg) Reqs/sec(Stdev) Reqs/sec(Max) Latency(Avg) Latency(Stdev) Latency(Max) Throughput
Gin 17106.22 1282.68 25141.96 57.22us 16.31us 4.13ms 3.33MB/s
Fiber 20799.90 2484.20 47345.97 46.87us 33.74us 8.53ms 3.75MB/s
Echo 16931.02 1514.14 23866.86 57.79us 24.29us 5.95ms 3.31MB/s
iris 16099.18 1906.67 38404.39 60.84us 40.52us 6.39ms 3.15MB/s
Aero 18089.56 1909.10 27211.90 54.03us 26.72us 4.78ms 2.48MB/s
Gorilla 16639.12 2032.12 23358.05 58.83us 51.22us 18.90ms 3.01MB/s
Chi 17083.86 1351.04 32302.24 57.28us 20.16us 3.90ms 3.24MB/s
beego 14867.76 2521.89 24303.04 65.97us 119.40us 34.81ms 2.89MB/s

single2.png

200コネクションで1000000リクエスト送った結果

フレームワーク Reqs/sec(Avg) Reqs/sec(Stdev) Reqs/sec(Max) Latency(Avg) Latency(Stdev) Latency(Max) Throughput
Gin 208636.02 25754.38 253525.30 597.28us 325.95us 12.29ms 40.63MB/s
Fiber 336809.43 55120.39 400314.69 369.63us 484.75us 31.42ms 60.67MB/s
Echo 205317.11 34161.60 249844.79 608.24us 356.58us 23.65ms 40.08MB/s
Iris 170416.71 55652.55 247878.33 732.21us 636.67us 25.55ms 33.29MB/s
Aero4 222673.49 47455.50 287053.07 560.91us 477.03us 27.47ms 30.53MB/s
Gorilla 193247.91 30438.74 248160.39 645.60us 463.03us 48.23ms 34.99MB/s
Chi 195821.22 49706.30 258315.63 637.03us 484.10us 27.10ms 37.11MB/s
Beego 148201.65 37780.27 200222.14 842.40us 760.16us 52.49ms 28.82MB/s

multi1.png

125コネクションで10秒間リクエストした結果

フレームワーク Reqs/sec(Avg) Reqs/sec(Stdev) Reqs/sec(Max) Latency(Avg) Latency(Stdev) Latency(Max) Throughput
Gin 189460.07 54921.14 266439.56 1.06ms 740.37us 50.99ms 36.83MB/s
Fiber 324226.98 59336.25 499175.37 616.27us 481.23us 37.24ms 58.33MB/s
Echo 205546.31 38669.41 255035.10 0.97ms 519.23us 26.75ms 40.16MB/s
iris 197964.44 36639.99 260544.20 1.01ms 529.77us 41.35ms 38.69MB/s
Aero 207057.97 55036.34 294250.62 0.96ms 509.91us 26.24ms 28.42MB/s
Gorilla 193298.12 28153.72 238842.58 1.03ms 529.80us 30.72ms 35.01MB/s
Chi 205582.09 39478.05 276359.19 0.97ms 512.48us 38.60ms 38.92MB/s
beego 171670.19 28420.81 216237.75 1.16ms 631.20us 33.14ms 33.38MB/s

multi2.png

まとめ

個人的にはGinが一番速いものだと思っていたのですが、今回のベンチマーク結果ではFiberがほとんどの場面で高パフォーマンスでした。環境や目的によって最適なフレームワークは変わると思うので、トレードオフを考えて、自分にあったベストなフレームワークを見つけましよう。

18
17
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
18
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?