fiber icon indicating copy to clipboard operation
fiber copied to clipboard

🚀 v3 Request: New Parser for Binding

Open efectn opened this issue 1 year ago • 6 comments

Feature Description

Currently, Fiber binding uses gorilla/schema and it's very slow and doesn't support multipart files (https://github.com/gofiber/fiber/issues/1967).

We should write more performant, powerful parser acording to the needs of Fiber.

Check: https://github.com/gofiber/fiber/pull/1981#issuecomment-1207505201

Additional Context (optional)

No response

Code Snippet (optional)

package main

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

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

  // An example to describe the feature

  log.Fatal(app.Listen(":3000"))
}

Checklist:

  • [X] I agree to follow Fiber's Code of Conduct.
  • [X] I have checked for existing issues that describe my suggestion prior to opening this one.
  • [X] I understand that improperly formatted feature requests may be closed without explanation.

efectn avatar Aug 08 '22 07:08 efectn

I'd like to add another context about this impl.

Key point here is not to use methods of fiber.Ctx, but to build a decoder for a Request struct and reuse it in the future.

with a function decorator, the decoder are pre-compiled and cached by nature. and this cached don't have overhead like map access.

If the decoder is not pre-compiled, it's not that fast and low alloc:

func Benchmark_lib_unmarshal(b *testing.B) {
	decode := inj.CompileParser(Req{})
	ctx := getCtx()
	for i := 0; i < b.N; i++ {
		_, err := decode(ctx)
		if err != nil {
			b.Error(err)
			b.FailNow()
		}
	}
}

func Benchmark_lib_unmarshal_with_compile(b *testing.B) {
- 	decode := inj.CompileParser(Req{})
	ctx := getCtx()
	for i := 0; i < b.N; i++ {
+		decode := inj.CompileParser(Req{})
		_, err := decode(ctx)
		if err != nil {
			b.Error(err)
			b.FailNow()
		}
	}
}
cpu: AMD Ryzen 7 5800X 8-Core Processor
Benchmark_unmarshal_by_hand-16                          14774758                68.03 ns/op            0 B/op          0 allocs/op
Benchmark_lib_unmarshal-16                               6359373               196.7 ns/op            96 B/op          2 allocs/op
Benchmark_lib_unmarshal_with_compile-16                  1222078               992.6 ns/op           672 B/op         22 allocs/op
BenchmarkGorillaSchema_map_to_struct_only-16              419390              2898 ns/op             904 B/op         49 allocs/op

trim21 avatar Aug 08 '22 14:08 trim21

if you have ideas or performance improvements, feel free to create a pull request with them and we'll see together how to get the best out of the respective functionalities.

any comments or improvements are always welcome

once the whole thing is released, it's hard to bend it, because non downward compatible changes require a new major version

ReneWerner87 avatar Aug 08 '22 14:08 ReneWerner87

I'll send a PR later

trim21 avatar Aug 08 '22 14:08 trim21

I want to know if the minimum go version that will be supported in the next release will be 1.18?

wangjq4214 avatar Aug 08 '22 23:08 wangjq4214

I guess yes https://github.com/gofiber/fiber/blob/v3-beta/go.mod#L3 , and my pr need new generic support .

trim21 avatar Aug 08 '22 23:08 trim21

I want to know if the minimum go version that will be supported in the next release will be 1.18?

Yes. v3 will support last 2 major versions of Go

efectn avatar Aug 09 '22 07:08 efectn