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  }