forked from gorilla/schema
-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Labels
Description
A simple benchmark case such as:
func BenchmarkSimpleStructDecode(b *testing.B) {
type S struct {
A string `schema:"a"`
B int `schema:"b"`
C bool `schema:"c"`
D float64 `schema:"d"`
E struct {
F float64 `schema:"f"`
} `schema:"e"`
}
s := S{}
data := map[string][]string{
"a": {"abc"},
"b": {"123"},
"c": {"true"},
"d": {"3.14"},
"e.f": {"3.14"},
}
decoder := NewDecoder()
b.ResetTimer()
for i := 0; i < b.N; i++ {
decoder.Decode(&s, data)
}
}
resulted with: BenchmarkSimpleStruct-16 326770 3600 ns/op 1072 B/op 58 allocs/op
which is quite expensive.
flat flat% sum% cum cum%
110.50MB 32.69% 32.69% 137.50MB 40.68% github.com/gofiber/schema.(*cache).parsePath
59.50MB 17.60% 50.29% 59.50MB 17.60% github.com/gofiber/schema.(*Decoder).findRequiredFields
32.50MB 9.61% 59.91% 32.50MB 9.61% reflect.(*structType).Field
30.50MB 9.02% 68.93% 30.50MB 9.02% reflect.New
29MB 8.58% 77.51% 48.50MB 14.35% github.com/gofiber/schema.(*Decoder).setDefaults
27MB 7.99% 85.50% 27MB 7.99% strings.genSplit
18MB 5.33% 90.82% 337.51MB 99.85% github.com/gofiber/schema.(*Decoder).Decode
14.50MB 4.29% 95.11% 14.50MB 4.29% reflect.packEface
6MB 1.78% 96.89% 6MB 1.78% github.com/gofiber/schema.convertString
3.50MB 1.04% 97.92% 3.50MB 1.04% reflect.makeFloat
these parts are the most expensive and memory-intensive parts according to pprof. I think there should be an open door to optimize parsePath, findRequiredFields and setDefaults logic. This PR is created to follow and find necessary optimizations.