FastAPI (Python) vs Echo (Go)

단순 호기심에 동일 기능을 벤치마크 해봤다. 언어의 성격이나 장단이 다르니 동일한 조건의 테스트는 아니라고 생각된다.

다른 파이썬 라이브러리로도 벤치마크 해봐야겠지만, 결론적으로는 Go 로 작성된 echo 프레임웍이 RPS 면이나 응답속도로도 압도적으로 빨랐다.

1. Env

  • apple m1 macbook air, osx v.11.6.2 bigsur, memory 16GB

2.FastAPI (Python), MysqlDB 연동 API

1) env

  • fastapi = "0.68.2"
  • aiomysql = "^0.0.22"
  • gunicorn = "^20.1.0"

2) 벤치마크

  • 테스트 소스
    테스트 소스는 지난 글에서 적용시킨 aiomysql 버전의 소스를 gunicorn 으로 구동 시켰다.
  • max connection 51 * workers 5 = 255
gunicorn apps.main:app --workers 5 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 --log-level critical
  • max connection 21 * workers 8 = 168
gunicorn apps.main:app --workers 8 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 --log-level critical

3.Echo (Go), MysqlDB 연동 API

1) env

  • github.com/labstack/echo/v4 v4.6.1
  • gorm.io/driver/mysql v1.2.2
  • gorm.io/gorm v1.22.4

2) 벤치마크

  • 테스트 소스
    echo 프레임웍으로 단순하게 구성했다.
package main

import (
	"fmt"
	"net/http"
	"strconv"
	"time"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"

	"github.com/labstack/echo/v4"
)

type (
	App struct {
		Idx     int    `json:"idx"`
		Regdate string `json:"regdate"`
		Title   string `json:"title"`
		Body    string `json:"body"`
	}
)

var (
	Apps = []App{}
)

func main() {
	dsn := "root:root@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Println(err.Error())
	} else {
		fmt.Println("db is connected")
	}
	sqlDB, _ := db.DB()
	sqlDB.SetMaxIdleConns(250)
	sqlDB.SetMaxOpenConns(250)
	sqlDB.SetConnMaxLifetime(time.Hour)

	//
	e := echo.New()
	e.GET("/memo/:page", func(c echo.Context) error {
		page := c.Param("page")
		limit := 10
		pint, _ := strconv.Atoi(page)
		offset := (pint - 1) * limit

		db.Table("memo").Offset(offset).Limit(10).Find(&Apps)

		return c.JSON(http.StatusOK, Apps)
	})
	e.Logger.Fatal(e.Start(":8000"))
}
  • max connection 22