github.com/alexflint/go-memdump@v1.1.0/bench/summarize.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "encoding/gob" 6 "encoding/json" 7 "fmt" 8 "os" 9 "time" 10 11 arg "github.com/alexflint/go-arg" 12 memdump "github.com/alexflint/go-memdump" 13 ) 14 15 type pathComponent struct { 16 S string 17 R int 18 } 19 20 type treeNode struct { 21 Label string 22 Weight int 23 Path []pathComponent 24 Children []*treeNode 25 } 26 27 func generateTree(depth, degree int) *treeNode { 28 tpl := treeNode{ 29 Label: "label", 30 Weight: 123, 31 Path: []pathComponent{ 32 {"abc", 4}, 33 {"def", 5}, 34 {"ghi", 6}, 35 }, 36 } 37 38 root := tpl 39 cur := []*treeNode{&root} 40 var next []*treeNode 41 for i := 1; i < depth; i++ { 42 for _, n := range cur { 43 for j := 0; j < degree; j++ { 44 ch := tpl 45 n.Children = append(n.Children, &ch) 46 next = append(next, &ch) 47 } 48 } 49 //log.Printf("at i=%d, len=%d", i, len(next)) 50 cur, next = next, cur[:0] 51 } 52 return &root 53 } 54 55 type codec interface { 56 name() string 57 encode(t *treeNode) ([]byte, error) 58 decode([]byte) error 59 } 60 61 type gobcodec struct{} 62 63 func (gobcodec) name() string { return "gob" } 64 65 func (gobcodec) encode(t *treeNode) ([]byte, error) { 66 var b bytes.Buffer 67 enc := gob.NewEncoder(&b) 68 err := enc.Encode(t) 69 if err != nil { 70 return nil, err 71 } 72 return b.Bytes(), nil 73 } 74 75 func (gobcodec) decode(buf []byte) error { 76 dec := gob.NewDecoder(bytes.NewBuffer(buf)) 77 var t treeNode 78 return dec.Decode(&t) 79 } 80 81 type jsoncodec struct{} 82 83 func (jsoncodec) name() string { return "json" } 84 85 func (jsoncodec) encode(t *treeNode) ([]byte, error) { 86 return json.Marshal(t) 87 } 88 89 func (jsoncodec) decode(buf []byte) error { 90 var t treeNode 91 return json.Unmarshal(buf, &t) 92 } 93 94 type memdumpcodec struct{} 95 96 func (memdumpcodec) name() string { return "memdump" } 97 98 func (memdumpcodec) encode(t *treeNode) ([]byte, error) { 99 var b bytes.Buffer 100 err := memdump.Encode(&b, t) 101 if err != nil { 102 return nil, err 103 } 104 return b.Bytes(), nil 105 } 106 107 func (memdumpcodec) decode(buf []byte) error { 108 var t *treeNode 109 return memdump.Decode(bytes.NewBuffer(buf), &t) 110 } 111 112 func main() { 113 var args struct { 114 Repeat int 115 Depth int 116 Degree int 117 } 118 args.Repeat = 5 119 args.Depth = 20 120 args.Degree = 2 121 arg.MustParse(&args) 122 123 t := generateTree(args.Depth, args.Degree) 124 125 fmt.Println("DECODE") 126 for _, codec := range []codec{gobcodec{}, jsoncodec{}, memdumpcodec{}} { 127 buf, err := codec.encode(t) 128 if err != nil { 129 fmt.Println(err) 130 os.Exit(1) 131 } 132 133 begin := time.Now() 134 for i := 0; i < args.Repeat; i++ { 135 err := codec.decode(buf) 136 if err != nil { 137 fmt.Println(err) 138 os.Exit(1) 139 } 140 } 141 duration := time.Since(begin).Seconds() / float64(args.Repeat) 142 143 bytesPerSec := float64(len(buf)) / duration 144 145 fmt.Printf("%20s %8.2f MB/s (%.1f MB in %.2fs)\n", 146 codec.name(), bytesPerSec/1000000., float64(len(buf))/1000000., duration) 147 } 148 149 fmt.Println("ENCODE") 150 for _, codec := range []codec{gobcodec{}, jsoncodec{}, memdumpcodec{}} { 151 buf, err := codec.encode(t) 152 if err != nil { 153 fmt.Println(err) 154 os.Exit(1) 155 } 156 157 begin := time.Now() 158 for i := 0; i < args.Repeat; i++ { 159 codec.encode(t) 160 } 161 duration := time.Since(begin).Seconds() / float64(args.Repeat) 162 163 bytesPerSec := float64(len(buf)) / duration 164 165 fmt.Printf("%20s %8.2f MB/s (%.1f MB in %.2fs)\n", 166 codec.name(), bytesPerSec/1000000., float64(len(buf))/1000000., duration) 167 } 168 }