initial commit
This commit is contained in:
commit
5491d961e4
31
README.md
Normal file
31
README.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# goapiperf
|
||||||
|
|
||||||
|
Benchmarks comparing jsoniter VS encoding/json and HTTP reuse
|
||||||
|
|
||||||
|
## Results (on my own hardware):
|
||||||
|
|
||||||
|
HTTP reuse:
|
||||||
|
```
|
||||||
|
goos: linux
|
||||||
|
goarch: amd64
|
||||||
|
pkg: apiSpeedImprove/httpReuse
|
||||||
|
cpu: AMD Ryzen 5 7640U w/ Radeon 760M Graphics
|
||||||
|
BenchmarkReusedHandler-12 2162 528014 ns/op
|
||||||
|
BenchmarkNewHandlerPerRequest-12 2329 497124 ns/op
|
||||||
|
PASS
|
||||||
|
ok apiSpeedImprove/httpReuse 7.193s
|
||||||
|
```
|
||||||
|
|
||||||
|
jsoniter:
|
||||||
|
```
|
||||||
|
goos: linux
|
||||||
|
goarch: amd64
|
||||||
|
pkg: apiSpeedImprove
|
||||||
|
cpu: AMD Ryzen 5 7640U w/ Radeon 760M Graphics
|
||||||
|
BenchmarkEncodingJSON-12 140383 7381 ns/op
|
||||||
|
BenchmarkJSONIter-12 974605 1217 ns/op
|
||||||
|
PASS
|
||||||
|
ok apiSpeedImprove 3.216s
|
||||||
|
```
|
||||||
|
|
||||||
|
Read the article [here](https://4rkal.com/posts/goapi)
|
9
go.mod
Normal file
9
go.mod
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module apiSpeedImprove
|
||||||
|
|
||||||
|
go 1.22.5
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
)
|
12
go.sum
Normal file
12
go.sum
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
46
httpReuse/httpReuse_test.go
Normal file
46
httpReuse/httpReuse_test.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func makeRequest(client *http.Client, url string) error {
|
||||||
|
resp, err := client.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkNewHttpClientEachRequest(b *testing.B) {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte("OK"))
|
||||||
|
}))
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
client := &http.Client{}
|
||||||
|
if err := makeRequest(client, server.URL); err != nil {
|
||||||
|
b.Fatalf("Request failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkReuseHttpClient(b *testing.B) {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte("OK"))
|
||||||
|
}))
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
client := &http.Client{} // Reusable HTTP client
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if err := makeRequest(client, server.URL); err != nil {
|
||||||
|
b.Fatalf("Request failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
83
jsoniter/jsonBenchmark_test.go
Normal file
83
jsoniter/jsonBenchmark_test.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
)
|
||||||
|
|
||||||
|
var jsonData = []byte(`{
|
||||||
|
"name": "Alice",
|
||||||
|
"age": 30,
|
||||||
|
"email": "alice@example.com",
|
||||||
|
"address": {
|
||||||
|
"street": "123 Maple Street",
|
||||||
|
"city": "Wonderland",
|
||||||
|
"postal_code": "12345"
|
||||||
|
},
|
||||||
|
"phones": [
|
||||||
|
{
|
||||||
|
"type": "home",
|
||||||
|
"number": "555-1234"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "work",
|
||||||
|
"number": "555-5678"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is_active": true,
|
||||||
|
"metadata": {
|
||||||
|
"created_at": "2024-08-16T10:00:00Z",
|
||||||
|
"updated_at": "2024-08-17T10:00:00Z"
|
||||||
|
},
|
||||||
|
"tags": ["developer", "golang", "openai"]
|
||||||
|
}`)
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Address Address
|
||||||
|
Phones []Phone
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
|
Metadata Metadata
|
||||||
|
Tags []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Phone struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Number string `json:"number"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Address struct {
|
||||||
|
Street string `json:"street"`
|
||||||
|
City string `json:"city"`
|
||||||
|
PostalCode string `json:"postal_code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Metadata struct {
|
||||||
|
CreatedAt string `json:"created_at"`
|
||||||
|
UpdatedAt string `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkEncodingJSON(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
var user User
|
||||||
|
err := json.Unmarshal(jsonData, &user)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatalf("Failed to unmarshal: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkJSONIter(b *testing.B) {
|
||||||
|
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
var user User
|
||||||
|
err := json.Unmarshal(jsonData, &user)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatalf("Failed to unmarshal: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user