...

Source file src/github.com/BurntSushi/toml/bench_test.go

Documentation: github.com/BurntSushi/toml

     1  //go:build go1.16
     2  // +build go1.16
     3  
     4  package toml_test
     5  
     6  import (
     7  	"bytes"
     8  	"io/fs"
     9  	"io/ioutil"
    10  	"os"
    11  	"path/filepath"
    12  	"sort"
    13  	"strings"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/BurntSushi/toml"
    18  	tomltest "github.com/BurntSushi/toml/internal/toml-test"
    19  )
    20  
    21  func BenchmarkDecode(b *testing.B) {
    22  	files := make(map[string][]string)
    23  	fs.WalkDir(tomltest.EmbeddedTests(), ".", func(path string, d fs.DirEntry, err error) error {
    24  		if strings.HasPrefix(path, "valid/") && strings.HasSuffix(path, ".toml") {
    25  			d, _ := fs.ReadFile(tomltest.EmbeddedTests(), path)
    26  			g := filepath.Dir(path[6:])
    27  			if g == "." {
    28  				g = "top"
    29  			}
    30  			files[g] = append(files[g], string(d))
    31  		}
    32  		return nil
    33  	})
    34  
    35  	type test struct {
    36  		group string
    37  		toml  []string
    38  	}
    39  	tests := make([]test, 0, len(files))
    40  	for k, v := range files {
    41  		tests = append(tests, test{group: k, toml: v})
    42  	}
    43  	sort.Slice(tests, func(i, j int) bool { return tests[i].group < tests[j].group })
    44  
    45  	b.ResetTimer()
    46  	for _, tt := range tests {
    47  		b.Run(tt.group, func(b *testing.B) {
    48  			b.ResetTimer()
    49  			for n := 0; n < b.N; n++ {
    50  				for _, f := range tt.toml {
    51  					var val map[string]interface{}
    52  					toml.Decode(f, &val)
    53  				}
    54  			}
    55  		})
    56  	}
    57  
    58  	b.Run("large-doc", func(b *testing.B) {
    59  		d, err := os.ReadFile("testdata/ja-JP.toml")
    60  		if err != nil {
    61  			b.Fatal(err)
    62  		}
    63  		doc := string(d)
    64  
    65  		b.ResetTimer()
    66  		for n := 0; n < b.N; n++ {
    67  			var val map[string]interface{}
    68  			toml.Decode(doc, &val)
    69  		}
    70  	})
    71  }
    72  
    73  func BenchmarkEncode(b *testing.B) {
    74  	files := make(map[string][]map[string]interface{})
    75  	fs.WalkDir(tomltest.EmbeddedTests(), ".", func(path string, d fs.DirEntry, err error) error {
    76  		if strings.HasPrefix(path, "valid/") && strings.HasSuffix(path, ".toml") {
    77  			d, _ := fs.ReadFile(tomltest.EmbeddedTests(), path)
    78  			g := filepath.Dir(path[6:])
    79  			if g == "." {
    80  				g = "top"
    81  			}
    82  
    83  			// "next" version of TOML.
    84  			switch path {
    85  			case "valid/string/escape-esc.toml", "valid/datetime/no-seconds.toml",
    86  				"valid/string/hex-escape.toml", "valid/inline-table/newline.toml",
    87  				"valid/key/unicode.toml":
    88  				return nil
    89  			}
    90  
    91  			var dec map[string]interface{}
    92  			_, err := toml.Decode(string(d), &dec)
    93  			if err != nil {
    94  				b.Fatalf("decode %q: %s", path, err)
    95  			}
    96  
    97  			buf := new(bytes.Buffer)
    98  			err = toml.NewEncoder(buf).Encode(dec)
    99  			if err != nil {
   100  				b.Logf("encode failed for %q (skipping): %s", path, err)
   101  				return nil
   102  			}
   103  
   104  			files[g] = append(files[g], dec)
   105  		}
   106  		return nil
   107  	})
   108  
   109  	type test struct {
   110  		group string
   111  		data  []map[string]interface{}
   112  	}
   113  	tests := make([]test, 0, len(files))
   114  	for k, v := range files {
   115  		tests = append(tests, test{group: k, data: v})
   116  	}
   117  	sort.Slice(tests, func(i, j int) bool { return tests[i].group < tests[j].group })
   118  
   119  	b.ResetTimer()
   120  	for _, tt := range tests {
   121  		b.Run(tt.group, func(b *testing.B) {
   122  			buf := new(bytes.Buffer)
   123  			buf.Grow(1024 * 64)
   124  			b.ResetTimer()
   125  			for n := 0; n < b.N; n++ {
   126  				for _, f := range tt.data {
   127  					toml.NewEncoder(buf).Encode(f)
   128  				}
   129  			}
   130  		})
   131  	}
   132  }
   133  
   134  func BenchmarkExample(b *testing.B) {
   135  	d, err := ioutil.ReadFile("_example/example.toml")
   136  	if err != nil {
   137  		b.Fatal(err)
   138  	}
   139  	t := string(d)
   140  
   141  	var decoded example
   142  	_, err = toml.Decode(t, &decoded)
   143  	if err != nil {
   144  		b.Fatal(err)
   145  	}
   146  
   147  	buf := new(bytes.Buffer)
   148  	err = toml.NewEncoder(buf).Encode(decoded)
   149  	if err != nil {
   150  		b.Fatal(err)
   151  	}
   152  
   153  	b.ResetTimer()
   154  	b.Run("decode", func(b *testing.B) {
   155  		for n := 0; n < b.N; n++ {
   156  			var c example
   157  			toml.Decode(t, &c)
   158  		}
   159  	})
   160  
   161  	b.Run("encode", func(b *testing.B) {
   162  		for n := 0; n < b.N; n++ {
   163  			buf.Reset()
   164  			toml.NewEncoder(buf).Encode(decoded)
   165  		}
   166  	})
   167  }
   168  
   169  // Copy from _example/example.go
   170  type (
   171  	example struct {
   172  		Title      string
   173  		Integers   []int
   174  		Times      []fmtTime
   175  		Duration   []duration
   176  		Distros    []distro
   177  		Servers    map[string]server
   178  		Characters map[string][]struct {
   179  			Name string
   180  			Rank string
   181  		}
   182  	}
   183  
   184  	server struct {
   185  		IP       string
   186  		Hostname string
   187  		Enabled  bool
   188  	}
   189  
   190  	distro struct {
   191  		Name     string
   192  		Packages string
   193  	}
   194  
   195  	duration struct{ time.Duration }
   196  	fmtTime  struct{ time.Time }
   197  )
   198  
   199  func (d *duration) UnmarshalText(text []byte) (err error) {
   200  	d.Duration, err = time.ParseDuration(string(text))
   201  	return err
   202  }
   203  
   204  func (t fmtTime) String() string {
   205  	f := "2006-01-02 15:04:05.999999999"
   206  	if t.Time.Hour() == 0 {
   207  		f = "2006-01-02"
   208  	}
   209  	if t.Time.Year() == 0 {
   210  		f = "15:04:05.999999999"
   211  	}
   212  	if t.Time.Location() == time.UTC {
   213  		f += " UTC"
   214  	} else {
   215  		f += " -0700"
   216  	}
   217  	return t.Time.Format(`"` + f + `"`)
   218  }
   219  

View as plain text