initial commit

This commit is contained in:
4rkal 2024-09-19 20:54:54 +03:00
commit 5491d961e4
5 changed files with 181 additions and 0 deletions

31
README.md Normal file
View 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
View 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
View 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=

View 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)
}
}
}

View 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)
}
}
}