Skip to content

Instantly share code, notes, and snippets.

@lithdew
Created May 11, 2020 08:02
Show Gist options
  • Save lithdew/76e37b4ed9bbbcf8c83450e20851823f to your computer and use it in GitHub Desktop.
Save lithdew/76e37b4ed9bbbcf8c83450e20851823f to your computer and use it in GitHub Desktop.
package flatend
import (
"encoding/json"
"strconv"
"testing"
"unsafe"
)
var _ json.Marshaler = (*SafePayload)(nil)
var _ json.Marshaler = (*UnsafePayload)(nil)
type SafePayload struct {
kv map[string]interface{}
}
func (p *SafePayload) Uint64(key string, val uint64) {
if p.kv == nil {
p.kv = make(map[string]interface{})
}
p.kv[key] = val
}
func (p *SafePayload) MarshalJSON() ([]byte, error) {
b := []byte{'{'}
i := 0
for k, v := range p.kv {
if i != 0 {
b = append(b, ',')
}
b = strconv.AppendQuote(b, k)
b = append(b, ':')
b = strconv.AppendUint(b, v.(uint64), 10)
i++
}
b = append(b, '}')
return b, nil
}
type UnsafePayload struct {
keys []string
values []unsafe.Pointer
}
func (p *UnsafePayload) Key(key string) {
p.keys = append(p.keys, key)
}
func (p *UnsafePayload) Uint64(key string, val uint64) {
p.keys = append(p.keys, key)
p.values = append(p.values, unsafe.Pointer(&val))
}
func (p *UnsafePayload) MarshalJSON() ([]byte, error) {
b := []byte{'{'}
for i := 0; i < len(p.keys); i++ {
if i != 0 {
b = append(b, ',')
}
b = strconv.AppendQuote(b, p.keys[i])
b = append(b, ':')
b = strconv.AppendUint(b, *(*uint64)(p.values[i]), 10)
}
b = append(b, '}')
return b, nil
}
func TestUnsafePayload(t *testing.T) {
var p UnsafePayload
p.Uint64("hello", 3)
p.Uint64("world", 65536)
p.Uint64("test", 1337)
buf, err := p.MarshalJSON()
if err != nil {
t.Error(err)
}
t.Log(string(buf))
}
func BenchmarkUnsafePayload(b *testing.B) {
p := &UnsafePayload{}
b.ReportAllocs()
b.ResetTimer()
for i := uint64(0); i < uint64(b.N); i++ {
p.Uint64("hello", i)
if i%100 == 0 {
p.keys = p.keys[:0]
p.values = p.values[:0]
}
}
}
func BenchmarkSafePayload(b *testing.B) {
p := &SafePayload{}
b.ReportAllocs()
b.ResetTimer()
for i := uint64(0); i < uint64(b.N); i++ {
p.Uint64("hello", i)
if i%100 == 0 {
for k := range p.kv {
delete(p.kv, k)
}
}
}
}
func BenchmarkUnsafePayloadMarshal(b *testing.B) {
p := &UnsafePayload{}
for i := uint64(0); i < 1024; i++ {
p.Uint64(string(i), i)
}
b.ReportAllocs()
b.ResetTimer()
var (
buf []byte
err error
)
for i := 0; i < b.N; i++ {
buf, err = p.MarshalJSON()
}
_, _ = buf, err
}
func BenchmarkSafePayloadMarshal(b *testing.B) {
p := &SafePayload{}
for i := uint64(0); i < 1024; i++ {
p.Uint64(string(i), i)
}
b.ReportAllocs()
b.ResetTimer()
var (
buf []byte
err error
)
for i := 0; i < b.N; i++ {
buf, err = p.MarshalJSON()
}
_, _ = buf, err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment