130 lines
2.8 KiB
Go
130 lines
2.8 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|||
|
|
// SPDX-License-Identifier: MIT
|
||
|
|
|
||
|
|
package interpres
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
// benchDoc is a representative configuration document: every scalar kind, an
|
||
|
|
// inline table, sub-tables, and an array of tables.
|
||
|
|
var benchDoc = []byte(`title = "benchmark configuration"
|
||
|
|
replicas = 3
|
||
|
|
ratio = 0.75
|
||
|
|
enabled = true
|
||
|
|
when = 2026-09-17T12:00:00Z
|
||
|
|
local = 2026-09-17T12:00:00
|
||
|
|
tags = ["alpha", "beta", "gamma"]
|
||
|
|
limits = { cpu = 4, memory = 1024 }
|
||
|
|
|
||
|
|
[server]
|
||
|
|
host = "localhost"
|
||
|
|
port = 8080
|
||
|
|
hosts = ["a.example", "b.example"]
|
||
|
|
|
||
|
|
[server.tls]
|
||
|
|
enabled = true
|
||
|
|
cert = "/etc/cert.pem"
|
||
|
|
|
||
|
|
[[items]]
|
||
|
|
name = "first"
|
||
|
|
weight = 10
|
||
|
|
flags = ["x", "y"]
|
||
|
|
|
||
|
|
[[items]]
|
||
|
|
name = "second"
|
||
|
|
weight = 20
|
||
|
|
flags = ["z"]
|
||
|
|
`)
|
||
|
|
|
||
|
|
// longDoc is generated once so the large-input benchmarks measure parsing,
|
||
|
|
// not document construction. Roughly 2000 array-of-tables entries.
|
||
|
|
var longDoc = func() []byte {
|
||
|
|
var b strings.Builder
|
||
|
|
b.WriteString("title = \"long\"\n")
|
||
|
|
for i := range 2000 {
|
||
|
|
fmt.Fprintf(&b, "[[entry]]\nname = \"entry-%d\"\nweight = %d\nwhen = 2026-09-17T12:00:00Z\nratio = 0.5\ntags = [\"a\", \"b\", \"c\"]\n\n", i, i)
|
||
|
|
}
|
||
|
|
return []byte(b.String())
|
||
|
|
}()
|
||
|
|
|
||
|
|
type benchTLS struct {
|
||
|
|
Enabled bool `toml:"enabled"`
|
||
|
|
Cert string `toml:"cert"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type benchServer struct {
|
||
|
|
Host string `toml:"host"`
|
||
|
|
Port int `toml:"port"`
|
||
|
|
Hosts []string `toml:"hosts"`
|
||
|
|
TLS benchTLS `toml:"tls"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type benchItem struct {
|
||
|
|
Name string `toml:"name"`
|
||
|
|
Weight int `toml:"weight"`
|
||
|
|
Flags []string `toml:"flags"`
|
||
|
|
}
|
||
|
|
|
||
|
|
type benchConfig struct {
|
||
|
|
Title string `toml:"title"`
|
||
|
|
Replicas int `toml:"replicas"`
|
||
|
|
Ratio float64 `toml:"ratio"`
|
||
|
|
Enabled bool `toml:"enabled"`
|
||
|
|
When time.Time `toml:"when"`
|
||
|
|
Local LocalDateTime `toml:"local"`
|
||
|
|
Tags []string `toml:"tags"`
|
||
|
|
Limits map[string]any `toml:"limits"`
|
||
|
|
Server benchServer `toml:"server"`
|
||
|
|
Items []benchItem `toml:"items"`
|
||
|
|
}
|
||
|
|
|
||
|
|
func BenchmarkParse(b *testing.B) {
|
||
|
|
b.ReportAllocs()
|
||
|
|
b.SetBytes(int64(len(benchDoc)))
|
||
|
|
for b.Loop() {
|
||
|
|
if _, err := Parse(benchDoc); err != nil {
|
||
|
|
b.Fatal(err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func BenchmarkMarshal(b *testing.B) {
|
||
|
|
tree, err := Parse(benchDoc)
|
||
|
|
if err != nil {
|
||
|
|
b.Fatal(err)
|
||
|
|
}
|
||
|
|
b.ReportAllocs()
|
||
|
|
b.SetBytes(int64(len(benchDoc)))
|
||
|
|
for b.Loop() {
|
||
|
|
if _, err := Marshal(tree); err != nil {
|
||
|
|
b.Fatal(err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func BenchmarkStrictDecode(b *testing.B) {
|
||
|
|
dec := NewDecoder().DisallowUnknownFields()
|
||
|
|
b.ReportAllocs()
|
||
|
|
for b.Loop() {
|
||
|
|
var cfg benchConfig
|
||
|
|
if err := dec.Decode(benchDoc, &cfg); err != nil {
|
||
|
|
b.Fatal(err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func BenchmarkParseLong(b *testing.B) {
|
||
|
|
b.ReportAllocs()
|
||
|
|
b.SetBytes(int64(len(longDoc)))
|
||
|
|
for b.Loop() {
|
||
|
|
if _, err := Parse(longDoc); err != nil {
|
||
|
|
b.Fatal(err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|