Open2
Potetoの水溜まり
PotetoはGolangのwebAPIフレームワーク
こんな感じで良い感じにroutingできる。
func main() {
p := poteto.New()
// Leaf >= 0.21.0
p.Leaf("/users", func(userApi poteto.Leaf) {
userApi.Register(middleware.CamaraWithConfig(middleware.DefaultCamaraConfig))
userApi.GET("/", controller.UserHandler)
userApi.GET("/:name", controller.UserIdHandler)
})
p.Run(":8000")
}
routingについての詳しい話はこちら
v0.23.4
アップデート
ルーターのパフォーマンスチューニングを行いました!!
パフォーマンスが2倍に
プルリク
変更内容
元々検索の際に、例えば
params := strings.Split(path, "/")
for _, param := range params {
...
}
のように配列を作ってループを回していました。この処理を以下のように毎回インデックスから取得するように変えました。
for {
id := strings.Index(rightPath, "/")
if id < 0 {
param = rightPath
} else {
param = rightPath[:id]
rightPath = rightPath[(id + 1):]
}
...
}
要因
これはstrings.Split()
が内部でループを挟むため、計算量が2Nになっていたことが原因です。
func genSplit(s, sep string, sepSave, n int) []string {
if n == 0 {
return nil
}
if sep == "" {
return explode(s, n)
}
if n < 0 {
n = Count(s, sep) + 1
}
if n > len(s)+1 {
n = len(s) + 1
}
a := make([]string, n)
n--
i := 0
for i < n {
m := Index(s, sep)
if m < 0 {
break
}
a[i] = s[:m+sepSave]
s = s[m+len(sep):]
i++
}
a[i] = s
return a[:i+1]
}
競プロとかではあまりNと2Nを区別している印象はないですが、webフレームワークはこれだけで捌けるリクエスト数が2倍になるので、大きな差があります