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