Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Golang Benchmark: gob vs json

tl;dr

  • gob is faster on Go1.7.1
    • map[int64]float64
    • []map[int64]float64

about

benchmark result to encode/decode map[int64]float64

Since Go1.7 encoding/json package supports map[int64]float64. So I tried to check the encoding perfomance of both old gob version and new json version, and if json version is better then I replace it from gob.

result

# Go1.7.1
$ go test -bench . -benchmem

# map[int64]float64 1000x1
BenchmarkEncodeGobMap-4         	   10000	    212167 ns/op	   76679 B/op	    2027 allocs/op
BenchmarkEncodeJSONMap-4        	    2000	    617791 ns/op	  120430 B/op	    3014 allocs/op
BenchmarkDecodeGobMap-4         	    3000	    485068 ns/op	  247927 B/op	    4284 allocs/op
BenchmarkDecodeJSONMap-4        	    2000	    785869 ns/op	  129814 B/op	    6101 allocs/op

# []map[int64]float64 1000x1000
BenchmarkEncodeGobSliceMap-4    	       5	 207572570 ns/op	83478294 B/op	 2002054 allocs/op
BenchmarkEncodeJSONSliceMap-4   	       2	 606564818 ns/op	119894280 B/op	 3004022 allocs/op
BenchmarkDecodeGobSliceMap-4    	       3	 445156171 ns/op	240279048 B/op	 4098939 allocs/op
BenchmarkDecodeJSONSliceMap-4   	       2	 779541167 ns/op	129597592 B/op	 6098888 allocs/op

gob performance compared to old versions.

# Go1.6.2
$ go test -bench Gob -benchmem

BenchmarkEncodeGobMap-4     	    5000	    238177 ns/op	   76813 B/op	    2027 allocs/op
BenchmarkDecodeGobMap-4     	    3000	    498338 ns/op	  247951 B/op	    4285 allocs/op
BenchmarkEncodeGobSliceMap-4	       5	 233456842 ns/op	83475468 B/op	 2002070 allocs/op
BenchmarkDecodeGobSliceMap-4	       3	 459773672 ns/op	240277658 B/op	 4098986 allocs/op
# Go1.5.4
$ go test -bench Gob -benchmem

BenchmarkEncodeGobMap-4     	    5000	    235427 ns/op	   92798 B/op	    2027 allocs/op
BenchmarkDecodeGobMap-4     	    2000	    643280 ns/op	  328328 B/op	    6287 allocs/op
BenchmarkEncodeGobSliceMap-4	       5	 232615195 ns/op	99475388 B/op	 2002056 allocs/op
BenchmarkDecodeGobSliceMap-4	       2	 574487306 ns/op	320285320 B/op	 6099054 allocs/op
# Go1.4.3
$ go test -bench Gob -benchmem

BenchmarkEncodeGobMap	    3000	    389002 ns/op	  108846 B/op	    3029 allocs/op
BenchmarkDecodeGobMap	    2000	    948001 ns/op	  318634 B/op	    6390 allocs/op
BenchmarkEncodeGobSliceMap	       5	 333594108 ns/op	115462483 B/op	 3002057 allocs/op
BenchmarkDecodeGobSliceMap	       2	 759865569 ns/op	302999312 B/op	 6067576 allocs/op

environment

  • OSX 10.11.6
  • CPU: Intel(R) Core(TM) i7-5557U CPU @ 3.10GHz
  • Memory: 16 GB
package main
import (
"bytes"
"encoding/gob"
"encoding/json"
)
func createMap(max int) map[int64]float64 {
m := make(map[int64]float64)
for i := 0; i < max; i++ {
m[int64(i)] = float64(i)
}
return m
}
func createSliceMap(max int) []map[int64]float64 {
list := make([]map[int64]float64, max)
for i := 0; i < max; i++ {
list[i] = createMap(max)
}
return list
}
func encodeGob(v interface{}) []byte {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
err := enc.Encode(v)
if err != nil {
panic(err)
}
return buf.Bytes()
}
func decodeGob(b []byte, result interface{}) {
buf := bytes.NewBuffer(b)
enc := gob.NewDecoder(buf)
err := enc.Decode(result)
if err != nil {
panic(err)
}
}
func encodeJSON(v interface{}) []byte {
byt, err := json.Marshal(v)
if err != nil {
panic(err)
}
return byt
}
func decodeJSON(b []byte, result interface{}) {
err := json.Unmarshal(b, result)
if err != nil {
panic(err)
}
}
package main
import "testing"
func BenchmarkEncodeGobMap(b *testing.B) {
m := createMap(1000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
res := encodeGob(m)
_ = res
}
}
func BenchmarkEncodeJSONMap(b *testing.B) {
m := createMap(1000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
res := encodeJSON(m)
_ = res
}
}
func BenchmarkDecodeGobMap(b *testing.B) {
m := createMap(1000)
byt := encodeGob(m)
b.ResetTimer()
for i := 0; i < b.N; i++ {
var result map[int64]float64
decodeGob(byt, &result)
}
}
func BenchmarkDecodeJSONMap(b *testing.B) {
m := createMap(1000)
byt := encodeJSON(m)
b.ResetTimer()
for i := 0; i < b.N; i++ {
var result map[int64]float64
decodeJSON(byt, &result)
}
}
func BenchmarkEncodeGobSliceMap(b *testing.B) {
m := createSliceMap(1000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
res := encodeGob(m)
_ = res
}
}
func BenchmarkEncodeJSONSliceMap(b *testing.B) {
m := createSliceMap(1000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
res := encodeJSON(m)
_ = res
}
}
func BenchmarkDecodeGobSliceMap(b *testing.B) {
m := createSliceMap(1000)
byt := encodeGob(m)
b.ResetTimer()
for i := 0; i < b.N; i++ {
var result []map[int64]float64
decodeGob(byt, &result)
}
}
func BenchmarkDecodeJSONSliceMap(b *testing.B) {
m := createSliceMap(1000)
byt := encodeJSON(m)
b.ResetTimer()
for i := 0; i < b.N; i++ {
var result []map[int64]float64
decodeJSON(byt, &result)
}
}
@devplayg

This comment has been minimized.

Copy link

@devplayg devplayg commented Aug 14, 2017

Very useful. Thank you for your efforts.

@pavelz

This comment has been minimized.

Copy link

@pavelz pavelz commented Jul 5, 2020

thank you!

@osamaroutemonkey

This comment has been minimized.

Copy link

@osamaroutemonkey osamaroutemonkey commented Oct 30, 2020

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment