-
-
Save up1/7c51506a3d05ffa2cc55434bfa045eaf to your computer and use it in GitHub Desktop.
Golang :: Compare JSON Serializer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 1. SonicSerializer implements echo.JSONSerializer using bytedance/sonic | |
| type SonicSerializer struct{} | |
| // Serialize converts a Go object into a JSON byte slice and writes it to the context | |
| func (s SonicSerializer) Serialize(c echo.Context, i interface{}, indent string) error { | |
| enc := sonic.ConfigDefault.NewEncoder(c.Response()) | |
| if indent != "" { | |
| enc.SetIndent("", indent) | |
| } | |
| return enc.Encode(i) | |
| } | |
| // Deserialize reads JSON from the request body and parses it into a Go object | |
| func (s SonicSerializer) Deserialize(c echo.Context, i interface{}) error { | |
| err := sonic.ConfigDefault.NewDecoder(c.Request().Body).Decode(i) | |
| if err != nil { | |
| return echo.NewHTTPError(http.StatusBadRequest, err.Error()) | |
| } | |
| return nil | |
| } | |
| // 2. V2Serializer implements echo.JSONSerializer using the standard library's encoding/json | |
| type V2Serializer struct{} | |
| func (s *V2Serializer) Serialize(c echo.Context, i interface{}, indent string) error { | |
| // Optional: Match Echo's internal indentation parameter if requested | |
| if indent != "" { | |
| return json.MarshalWrite(c.Response(), i, jsontext.WithIndent(indent)) | |
| } | |
| return json.MarshalWrite(c.Response(), i) | |
| } | |
| func (s *V2Serializer) Deserialize(c echo.Context, i interface{}) error { | |
| err := json.UnmarshalRead(c.Request().Body, i) | |
| if err != nil { | |
| return echo.NewHTTPError(http.StatusBadRequest, err.Error()) | |
| } | |
| return nil | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // User payload for testing | |
| type User struct { | |
| ID int `json:"id"` | |
| Name string `json:"name"` | |
| Email string `json:"email"` | |
| // Add 5 layers of nested structs to increase complexity | |
| Profile struct { | |
| Address struct { | |
| Street string `json:"street"` | |
| City string `json:"city"` | |
| State string `json:"state"` | |
| Zip string `json:"zip"` | |
| Geo struct { | |
| Lat float64 `json:"lat"` | |
| Lng float64 `json:"lng"` | |
| } `json:"geo"` | |
| } `json:"address"` | |
| PhoneNumbers []struct { | |
| Type string `json:"type"` | |
| Number string `json:"number"` | |
| } `json:"phone_numbers"` | |
| } `json:"profile"` | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func BenchmarkEchoJSON(b *testing.B) { | |
| // 1. Setup Standard Echo | |
| eStd := echo.New() | |
| // 2. Setup Sonic Echo | |
| eSonic := echo.New() | |
| eSonic.JSONSerializer = &demo.SonicSerializer{} | |
| // 3. Setup json v2 Echo | |
| easyjson := echo.New() | |
| easyjson.JSONSerializer = &demo.V2Serializer{} | |
| // Target Handler | |
| handler := func(c echo.Context) error { | |
| u := new(User) | |
| if err := c.Bind(u); err != nil { | |
| return err | |
| } | |
| return c.JSON(http.StatusOK, u) | |
| } | |
| eStd.POST("/user", handler) | |
| eSonic.POST("/user", handler) | |
| easyjson.POST("/user", handler) | |
| jsonPayload := []byte(`{ | |
| "id": 1, | |
| "name": "John Doe", | |
| "email": "john.doe@example.com", | |
| "profile": { | |
| "address": { | |
| "street": "123 Main St", | |
| "city": "Anytown", | |
| "state": "CA", | |
| "zip": "12345", | |
| "geo": { | |
| "lat": 37.7749, | |
| "lng": -122.4194 | |
| } | |
| }, | |
| "phone_numbers": [ | |
| { | |
| "type": "home", | |
| "number": "555-555-5555" | |
| }, | |
| { | |
| "type": "work", | |
| "number": "555-555-5556" | |
| } | |
| ] | |
| } | |
| }`) | |
| // Run Standard Benchmark | |
| b.Run("Standard_JSON", func(b *testing.B) { | |
| b.ReportAllocs() | |
| for i := 0; i < b.N; i++ { | |
| req := httptest.NewRequest(http.MethodPost, "/user", bytes.NewReader(jsonPayload)) | |
| req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) | |
| rec := httptest.NewRecorder() | |
| eStd.ServeHTTP(rec, req) | |
| } | |
| }) | |
| // Run Sonic Benchmark | |
| b.Run("Sonic_JSON", func(b *testing.B) { | |
| b.ReportAllocs() | |
| for i := 0; i < b.N; i++ { | |
| req := httptest.NewRequest(http.MethodPost, "/user", bytes.NewReader(jsonPayload)) | |
| req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) | |
| rec := httptest.NewRecorder() | |
| eSonic.ServeHTTP(rec, req) | |
| } | |
| }) | |
| // Run json v2 Benchmark | |
| b.Run("JSON_V2", func(b *testing.B) { | |
| b.ReportAllocs() | |
| for i := 0; i < b.N; i++ { | |
| req := httptest.NewRequest(http.MethodPost, "/user", bytes.NewReader(jsonPayload)) | |
| req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) | |
| rec := httptest.NewRecorder() | |
| easyjson.ServeHTTP(rec, req) | |
| } | |
| }) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $go version | |
| go version go1.26.5 darwin/arm64 | |
| $go test -bench=. -benchmem -cpu=6 | |
| goos: darwin | |
| goarch: arm64 | |
| pkg: demo | |
| cpu: Apple M2 Max | |
| BenchmarkEchoJSON/Standard_JSON-6 214736 5661 ns/op 9587 B/op 42 allocs/op | |
| BenchmarkEchoJSON/Sonic_JSON-6 288771 3991 ns/op 11233 B/op 33 allocs/op | |
| BenchmarkEchoJSON/JSON_V2-6 287110 4251 ns/op 7314 B/op 30 allocs/op |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment