-
-
Save UlricQin/cc188408eeaf7c5c08a4379cbbe614fc to your computer and use it in GitHub Desktop.
BSON vs. Gob vs. MessagePack encoding & decoding benchmark
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
package main | |
import ( | |
"bytes" | |
"encoding/gob" | |
"fmt" | |
"github.com/ugorji/go/codec" | |
"io/ioutil" | |
"labix.org/v2/mgo" | |
"labix.org/v2/mgo/bson" | |
"path" | |
"time" | |
) | |
const ( | |
DISK_FILE_DIR = "/Users/Eric/Desktop" | |
DISK_FILE_NAME = "sampleobj" | |
MONGO_URL = "mongodb://172.18.1.1" | |
MONGO_DB = "giraffe" | |
MONGO_COLL = "benchmark.codec" | |
) | |
const ( | |
SAMPLE_STRING = `JavaScript is the behavior, 测试, the third pillar in today's paradigm that looks at web pages as something that consists of clearly distinguishable parts: content (HTML), presentation (CSS) and behavior (JavaScript). Using JavaScript, you can create not only web pages but also desktop widgets, browser and application extensions, and other pieces of software. It's a pretty good deal: you learn one language and then code all kinds of different applications. While there's one chapter specifically dedicated to the web browser environment including DOM, Events and AJAX tutorials, the rest is applicable to the other environments. | |
Many web developers have tried coding or adopting some bits of JavaScript, but it is time to "man up" and learn the language properly because it is the language of the browser and is, virtually, everywhere. This book starts from zero, not assuming any prior JavaScript programming knowledge and takes you through all the in-depth and exciting futures hidden behind the facade. | |
Once listed in the "nice to have" sections of job postings, these days the knowledge of JavaScript is a deciding factor when it comes to hiring web developers. After reading this book you'll be prepared to ace your JavaScript job interview and even impress with some bits that the interviewer maybe didn't know. You should read this book if you want to be able to take your JavaScript skills to a new level of sophistication.` | |
) | |
type EncodeFunction func(map[string]interface{}) (time.Duration, []byte, error) | |
type DecodeFunction func([]byte) (time.Duration, map[string]interface{}, error) | |
var ( | |
sampleObject = map[string]interface{}{ | |
"bookID": "538b5a2404e26d9ad4000003", | |
"title": "Raspberry Pi Home Automation with Arduino", | |
"abstract": SAMPLE_STRING, | |
"time": time.Now().UTC(), | |
"cover": map[string]interface{}{ | |
"dim": "615,791", | |
"path": "http://giraffe.oss-cn-qingdao.aliyuncs.com/giraffe/cover/2014/538b614604e26d9ad4000004_7sdqsg.jpg", | |
}, | |
"publish_year": 2013, | |
"publish_month": 2, | |
"publisher": "Packt", | |
"long": int64(987125478598), | |
"rate": 5.588888, | |
"pages": 239, | |
"price": 5, | |
"editorRate": -2, | |
"volume": 0, | |
"edition": 2, | |
"category": 1, | |
"language": "en", | |
"isbn": []string{"978-1-84969-586-2", "1-84969-586-2"}, | |
"isbn_empty": []string{}, | |
"preview": nil, | |
"comment": "", | |
"authors": []string{"", "Andrew K. Dennis", "𠀾\U00020024"}, | |
"formats": []map[string]interface{}{ | |
map[string]interface{}{"format": 1, "path": "abc"}, | |
map[string]interface{}{"format": 2, "path": "defg"}, | |
}, | |
"tags": []interface{}{ | |
"raspberry pi", | |
map[string]interface{}{ | |
"key": "someKey", | |
"value": map[string]interface{}{ | |
"sub-key": "someSubKey", | |
"sub-value": []float64{-9999.0, 88.0}, | |
}, | |
}, | |
-8888, | |
12.34567, | |
}, | |
"society": map[string]interface{}{ | |
"purchase": 0, | |
"favorite": 0, | |
"wishlist": 2, | |
"rateTimes": 100, | |
"rateTotal": 480, | |
"rate": 4.8, | |
"comment": 50, | |
}, | |
} | |
) | |
func main() { | |
gob.Register(time.Time{}) | |
gob.Register([]interface{}{}) | |
gob.Register(map[string]interface{}{}) | |
gob.Register([]map[string]interface{}{}) | |
runEncodings() | |
runDecodings() | |
} | |
func runEncodings() { | |
type Wrapper struct { | |
Name string // encoding method name | |
Extention string // output file extention | |
Function EncodeFunction // encoding function | |
} | |
encodings := []*Wrapper{ | |
&Wrapper{"BSON", "bson", encodeBSON}, | |
&Wrapper{"Gob", "gob", encodeGob}, | |
&Wrapper{"MessagePack", "msgpack", encodeMessagePack}, | |
} | |
fmt.Println("================ Encoding ================") | |
for _, w := range encodings { | |
d, b, err := w.Function(sampleObject) | |
if err != nil { | |
fmt.Printf("%-12s ERROR: %@\n", w.Name, err.Error()) | |
continue | |
} | |
fmt.Printf("%-12s: time=%#8.3fμs, size=%d\n", w.Name, float64(d)/1e3, len(b)) | |
// write encoding result to disk | |
fileName := fmt.Sprintf("%s.%s", DISK_FILE_NAME, w.Extention) | |
outputPath := path.Join(DISK_FILE_DIR, fileName) | |
err = ioutil.WriteFile(outputPath, b, 0644) | |
if err != nil { | |
panic(err) | |
} | |
} | |
fmt.Println("================== Done ==================") | |
} | |
func runDecodings() { | |
type Wrappewr struct { | |
Name string // decosing method name | |
Extention string // input file extention | |
Function DecodeFunction // decoding function | |
} | |
decodings := []*Wrappewr{ | |
&Wrappewr{"BSON", "bson", decodeBSON}, | |
&Wrappewr{"Gob", "gob", decodeGob}, | |
&Wrappewr{"MessagePack", "msgpack", decodeMessagePack}, | |
} | |
fmt.Println("================ Decoding ================") | |
doc := bson.M{ | |
"_id": time.Now(), | |
} | |
for _, w := range decodings { | |
// read disk file | |
fileName := fmt.Sprintf("%s.%s", DISK_FILE_NAME, w.Extention) | |
inputPath := path.Join(DISK_FILE_DIR, fileName) | |
b, err := ioutil.ReadFile(inputPath) | |
if err != nil { | |
fmt.Printf("%-12s ERROR: %@\n", w.Name, err.Error()) | |
continue | |
} | |
d, v, err := w.Function(b) | |
if err != nil { | |
fmt.Printf("%-12s ERROR: %@\n", w.Name, err.Error()) | |
continue | |
} | |
fmt.Printf("%-12s: time=%#8.3fus\n", w.Name, float64(d)/1e3) | |
doc[w.Name] = v | |
} | |
// write results to MongoDB | |
session, err := mgo.Dial(MONGO_URL) | |
if err != nil { | |
panic(err) | |
} | |
defer session.Close() | |
err = session.DB(MONGO_DB).C(MONGO_COLL).Insert(doc) | |
if err != nil { | |
panic(err) | |
} | |
fmt.Println("================== Done ==================") | |
} | |
//////////////////////////////////////////////////////////////////////////////////// | |
//////////////////////////////////////////////////////////////////////////////////// | |
func encodeBSON(obj map[string]interface{}) (time.Duration, []byte, error) { | |
beginTime := time.Now() | |
b, err := bson.Marshal(obj) | |
if err != nil { | |
return 0.0, nil, err | |
} | |
d := time.Now().Sub(beginTime) | |
return d, b, nil | |
} | |
func encodeGob(obj map[string]interface{}) (time.Duration, []byte, error) { | |
beginTime := time.Now() | |
buff := new(bytes.Buffer) | |
encoder := gob.NewEncoder(buff) | |
err := encoder.Encode(obj) | |
if err != nil { | |
return 0.0, nil, err | |
} | |
b := buff.Bytes() | |
d := time.Now().Sub(beginTime) | |
return d, b, nil | |
} | |
func encodeMessagePack(obj map[string]interface{}) (time.Duration, []byte, error) { | |
beginTime := time.Now() | |
var handler codec.MsgpackHandle | |
buff := new(bytes.Buffer) | |
encoder := codec.NewEncoder(buff, &handler) | |
err := encoder.Encode(obj) | |
if err != nil { | |
return 0.0, nil, err | |
} | |
b := buff.Bytes() | |
d := time.Now().Sub(beginTime) | |
return d, b, nil | |
} | |
//////////////////////////////////////////////////////////////////////////////////// | |
//////////////////////////////////////////////////////////////////////////////////// | |
func decodeBSON(b []byte) (time.Duration, map[string]interface{}, error) { | |
beginTime := time.Now() | |
var v map[string]interface{} | |
err := bson.Unmarshal(b, &v) | |
if err != nil { | |
return 0.0, nil, err | |
} | |
d := time.Now().Sub(beginTime) | |
return d, v, nil | |
} | |
func decodeGob(b []byte) (time.Duration, map[string]interface{}, error) { | |
beginTime := time.Now() | |
var v map[string]interface{} | |
buff := bytes.NewBuffer(b) | |
decoder := gob.NewDecoder(buff) | |
err := decoder.Decode(&v) | |
if err != nil { | |
return 0.0, nil, err | |
} | |
d := time.Now().Sub(beginTime) | |
return d, v, nil | |
} | |
func decodeMessagePack(b []byte) (time.Duration, map[string]interface{}, error) { | |
beginTime := time.Now() | |
var handler codec.MsgpackHandle | |
var v map[string]interface{} | |
decoder := codec.NewDecoderBytes(b, &handler) | |
err := decoder.Decode(&v) | |
if err != nil { | |
return 0.0, nil, err | |
} | |
d := time.Now().Sub(beginTime) | |
return d, v, 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
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 58.922μs, size=2382 | |
Gob : time= 412.141μs, size=2759 | |
MessagePack : time= 51.395μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 61.721us | |
Gob : time= 260.801us | |
MessagePack : time= 82.010us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 60.732μs, size=2382 | |
Gob : time= 420.968μs, size=2759 | |
MessagePack : time= 57.369μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 60.554us | |
Gob : time= 273.868us | |
MessagePack : time= 82.861us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 66.724μs, size=2382 | |
Gob : time= 425.433μs, size=2759 | |
MessagePack : time= 57.988μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 62.214us | |
Gob : time= 252.656us | |
MessagePack : time= 82.146us | |
================== Done ================== | |
Desktop ➤ | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 63.632μs, size=2382 | |
Gob : time= 396.575μs, size=2759 | |
MessagePack : time= 52.121μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 63.454us | |
Gob : time= 269.334us | |
MessagePack : time= 78.278us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 64.367μs, size=2382 | |
Gob : time= 396.325μs, size=2759 | |
MessagePack : time= 62.658μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 62.867us | |
Gob : time= 268.532us | |
MessagePack : time= 79.308us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 69.458μs, size=2382 | |
Gob : time= 423.515μs, size=2759 | |
MessagePack : time= 56.863μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 62.490us | |
Gob : time= 252.000us | |
MessagePack : time= 90.509us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 58.875μs, size=2382 | |
Gob : time= 403.429μs, size=2758 | |
MessagePack : time= 50.493μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 59.615us | |
Gob : time= 256.975us | |
MessagePack : time= 94.732us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 64.077μs, size=2382 | |
Gob : time= 398.299μs, size=2759 | |
MessagePack : time= 52.327μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 93.343us | |
Gob : time= 325.189us | |
MessagePack : time= 69.840us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 65.793μs, size=2382 | |
Gob : time= 411.302μs, size=2759 | |
MessagePack : time= 53.875μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 61.903us | |
Gob : time= 275.300us | |
MessagePack : time= 65.369us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 60.651μs, size=2382 | |
Gob : time= 409.052μs, size=2758 | |
MessagePack : time= 51.147μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 59.323us | |
Gob : time= 256.700us | |
MessagePack : time= 83.984us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 60.576μs, size=2382 | |
Gob : time= 424.650μs, size=2758 | |
MessagePack : time= 51.628μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 60.147us | |
Gob : time= 258.529us | |
MessagePack : time= 84.448us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 64.550μs, size=2382 | |
Gob : time= 392.359μs, size=2759 | |
MessagePack : time= 51.921μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 62.711us | |
Gob : time= 296.202us | |
MessagePack : time= 103.330us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 64.432μs, size=2382 | |
Gob : time= 426.694μs, size=2759 | |
MessagePack : time= 52.000μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 76.070us | |
Gob : time= 271.120us | |
MessagePack : time= 67.436us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 60.628μs, size=2382 | |
Gob : time= 408.804μs, size=2759 | |
MessagePack : time= 50.180μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 62.212us | |
Gob : time= 274.868us | |
MessagePack : time= 82.234us | |
================== Done ================== | |
Desktop ➤ ./main | |
================ Encoding ================ | |
BSON : time= 66.879μs, size=2382 | |
Gob : time= 418.987μs, size=2759 | |
MessagePack : time= 63.126μs, size=2156 | |
================== Done ================== | |
================ Decoding ================ | |
BSON : time= 68.319us | |
Gob : time= 271.848us | |
MessagePack : time= 82.848us | |
================== Done ================== |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment