diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 17:02:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 17:02:14 +0000 |
commit | e61c5fa98419989a61b5ca4eb7749acbd37e0af6 (patch) | |
tree | ffe04b0283921bd40489aaa74dcee1f68b7b6b35 /bench_test.go | |
parent | Initial commit. (diff) | |
download | golang-toml-e61c5fa98419989a61b5ca4eb7749acbd37e0af6.tar.xz golang-toml-e61c5fa98419989a61b5ca4eb7749acbd37e0af6.zip |
Adding upstream version 1.3.2.upstream/1.3.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'bench_test.go')
-rw-r--r-- | bench_test.go | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/bench_test.go b/bench_test.go new file mode 100644 index 0000000..198ce5c --- /dev/null +++ b/bench_test.go @@ -0,0 +1,218 @@ +//go:build go1.16 +// +build go1.16 + +package toml_test + +import ( + "bytes" + "io/fs" + "io/ioutil" + "os" + "path/filepath" + "sort" + "strings" + "testing" + "time" + + "github.com/BurntSushi/toml" + tomltest "github.com/BurntSushi/toml/internal/toml-test" +) + +func BenchmarkDecode(b *testing.B) { + files := make(map[string][]string) + fs.WalkDir(tomltest.EmbeddedTests(), ".", func(path string, d fs.DirEntry, err error) error { + if strings.HasPrefix(path, "valid/") && strings.HasSuffix(path, ".toml") { + d, _ := fs.ReadFile(tomltest.EmbeddedTests(), path) + g := filepath.Dir(path[6:]) + if g == "." { + g = "top" + } + files[g] = append(files[g], string(d)) + } + return nil + }) + + type test struct { + group string + toml []string + } + tests := make([]test, 0, len(files)) + for k, v := range files { + tests = append(tests, test{group: k, toml: v}) + } + sort.Slice(tests, func(i, j int) bool { return tests[i].group < tests[j].group }) + + b.ResetTimer() + for _, tt := range tests { + b.Run(tt.group, func(b *testing.B) { + b.ResetTimer() + for n := 0; n < b.N; n++ { + for _, f := range tt.toml { + var val map[string]interface{} + toml.Decode(f, &val) + } + } + }) + } + + b.Run("large-doc", func(b *testing.B) { + d, err := os.ReadFile("testdata/ja-JP.toml") + if err != nil { + b.Fatal(err) + } + doc := string(d) + + b.ResetTimer() + for n := 0; n < b.N; n++ { + var val map[string]interface{} + toml.Decode(doc, &val) + } + }) +} + +func BenchmarkEncode(b *testing.B) { + files := make(map[string][]map[string]interface{}) + fs.WalkDir(tomltest.EmbeddedTests(), ".", func(path string, d fs.DirEntry, err error) error { + if strings.HasPrefix(path, "valid/") && strings.HasSuffix(path, ".toml") { + d, _ := fs.ReadFile(tomltest.EmbeddedTests(), path) + g := filepath.Dir(path[6:]) + if g == "." { + g = "top" + } + + // "next" version of TOML. + switch path { + case "valid/string/escape-esc.toml", "valid/datetime/no-seconds.toml", + "valid/string/hex-escape.toml", "valid/inline-table/newline.toml", + "valid/key/unicode.toml": + return nil + } + + var dec map[string]interface{} + _, err := toml.Decode(string(d), &dec) + if err != nil { + b.Fatalf("decode %q: %s", path, err) + } + + buf := new(bytes.Buffer) + err = toml.NewEncoder(buf).Encode(dec) + if err != nil { + b.Logf("encode failed for %q (skipping): %s", path, err) + return nil + } + + files[g] = append(files[g], dec) + } + return nil + }) + + type test struct { + group string + data []map[string]interface{} + } + tests := make([]test, 0, len(files)) + for k, v := range files { + tests = append(tests, test{group: k, data: v}) + } + sort.Slice(tests, func(i, j int) bool { return tests[i].group < tests[j].group }) + + b.ResetTimer() + for _, tt := range tests { + b.Run(tt.group, func(b *testing.B) { + buf := new(bytes.Buffer) + buf.Grow(1024 * 64) + b.ResetTimer() + for n := 0; n < b.N; n++ { + for _, f := range tt.data { + toml.NewEncoder(buf).Encode(f) + } + } + }) + } +} + +func BenchmarkExample(b *testing.B) { + d, err := ioutil.ReadFile("_example/example.toml") + if err != nil { + b.Fatal(err) + } + t := string(d) + + var decoded example + _, err = toml.Decode(t, &decoded) + if err != nil { + b.Fatal(err) + } + + buf := new(bytes.Buffer) + err = toml.NewEncoder(buf).Encode(decoded) + if err != nil { + b.Fatal(err) + } + + b.ResetTimer() + b.Run("decode", func(b *testing.B) { + for n := 0; n < b.N; n++ { + var c example + toml.Decode(t, &c) + } + }) + + b.Run("encode", func(b *testing.B) { + for n := 0; n < b.N; n++ { + buf.Reset() + toml.NewEncoder(buf).Encode(decoded) + } + }) +} + +// Copy from _example/example.go +type ( + example struct { + Title string + Integers []int + Times []fmtTime + Duration []duration + Distros []distro + Servers map[string]server + Characters map[string][]struct { + Name string + Rank string + } + } + + server struct { + IP string + Hostname string + Enabled bool + } + + distro struct { + Name string + Packages string + } + + duration struct{ time.Duration } + fmtTime struct{ time.Time } +) + +func (d *duration) UnmarshalText(text []byte) (err error) { + d.Duration, err = time.ParseDuration(string(text)) + return err +} + +func (t fmtTime) String() string { + f := "2006-01-02 15:04:05.999999999" + if t.Time.Hour() == 0 { + f = "2006-01-02" + } + if t.Time.Year() == 0 { + f = "15:04:05.999999999" + } + if t.Time.Location() == time.UTC { + f += " UTC" + } else { + f += " -0700" + } + return t.Time.Format(`"` + f + `"`) +} |