Add benchmarks results to readme (#548)

This commit is contained in:
Thomas Pelletier
2021-06-01 09:10:17 -04:00
committed by GitHub
parent 250e073408
commit b202375414
2 changed files with 120 additions and 17 deletions
+43 -11
View File
@@ -4,7 +4,6 @@ Go library for the [TOML](https://toml.io/en/) format.
This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0). This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0).
## Development status ## Development status
This is the upcoming major version of go-toml. It is currently in active This is the upcoming major version of go-toml. It is currently in active
@@ -20,14 +19,12 @@ encouraged to try out this version.
[💬 Anything else](https://github.com/pelletier/go-toml/discussions) [💬 Anything else](https://github.com/pelletier/go-toml/discussions)
## Documentation ## Documentation
Full API, examples, and implementation notes are available in the Go documentation. Full API, examples, and implementation notes are available in the Go documentation.
[![Go Reference](https://pkg.go.dev/badge/github.com/pelletier/go-toml/v2.svg)](https://pkg.go.dev/github.com/pelletier/go-toml/v2) [![Go Reference](https://pkg.go.dev/badge/github.com/pelletier/go-toml/v2.svg)](https://pkg.go.dev/github.com/pelletier/go-toml/v2)
## Import ## Import
```go ```go
@@ -44,7 +41,7 @@ standard library's `encoding/json`.
### Performance ### Performance
While go-toml favors usability, it is written with performance in mind. Most While go-toml favors usability, it is written with performance in mind. Most
operations should not be shockingly slow. operations should not be shockingly slow. See [benchmarks](#benchmarks).
### Strict mode ### Strict mode
@@ -150,6 +147,43 @@ fmt.Println(string(b))
[marshal]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#Marshal [marshal]: https://pkg.go.dev/github.com/pelletier/go-toml/v2#Marshal
## Benchmarks
Execution time speedup compared to other Go TOML libraries:
<table>
<thead>
<tr><th>Benchmark</th><th>go-toml v1</th><th>BurntSushi/toml</th></tr>
</thead>
<tbody>
<tr><td>HugoFrontMatter</td><td>2.6x</td><td>2.2x</td></tr>
<tr><td>ReferenceFile/map</td><td>2.8x</td><td>3.0x</td></tr>
<tr><td>ReferenceFile/struct</td><td>5.4x</td><td>6.2x</td></tr>
</tbody>
</table>
<details><summary>See more</summary>
<p>The table above has the results of the most common use-cases. The table
below contains the results of all benchmarks, including unrealistic ones. is
provided for completeness.</p>
<table>
<thead>
<tr><th>Benchmark</th><th>go-toml v1</th><th>BurntSushi/toml</th></tr>
</thead>
<tbody>
<tr><td>UnmarshalSimple/map</td><td>3.8x</td><td>2.4x</td></tr>
<tr><td>UnmarshalSimple/struct</td><td>5.4x</td><td>3.1x</td></tr>
<tr><td>UnmarshalDataset/example</td><td>2.8x</td><td>2.0x</td></tr>
<tr><td>UnmarshalDataset/code</td><td>1.8x</td><td>2.2x</td></tr>
<tr><td>UnmarshalDataset/twitter</td><td>2.5x</td><td>1.8x</td></tr>
<tr><td>UnmarshalDataset/citm_catalog</td><td>1.9x</td><td>1.2x</td></tr>
<tr><td>UnmarshalDataset/config</td><td>3.0x</td><td>2.5x</td></tr>
<tr><td>[Geo mean]</td><td>3.0x</td><td>2.4x</td></tr>
</tbody>
</table>
<p>This table can be generated with <code>./ci.sh benchmark -a -html</code>.</p>
</details>
## Migrating from v1 ## Migrating from v1
This section describes the differences between v1 and v2, with some pointers on This section describes the differences between v1 and v2, with some pointers on
@@ -191,7 +225,7 @@ d := doc{
} }
data := ` data := `
[A] [A]
B = "After" B = "After"
` `
@@ -252,7 +286,6 @@ This method was not widely used, poorly defined, and added a lot of complexity.
A similar effect can be achieved by implementing the `encoding.TextUnmarshaler` A similar effect can be achieved by implementing the `encoding.TextUnmarshaler`
interface and use strings. interface and use strings.
#### Support for `default` struct tag has been dropped #### Support for `default` struct tag has been dropped
This feature adds complexity and a poorly defined API for an effect that can be This feature adds complexity and a poorly defined API for an effect that can be
@@ -311,7 +344,6 @@ manually sort the fields alphabetically in the struct definition.
V1 automatically indents content of tables by default. V2 does not. However the V1 automatically indents content of tables by default. V2 does not. However the
same behavior can be obtained using [`Encoder.SetIndentTables`][sit]. For example: same behavior can be obtained using [`Encoder.SetIndentTables`][sit]. For example:
```go ```go
data := map[string]interface{}{ data := map[string]interface{}{
"table": map[string]string{ "table": map[string]string{
@@ -333,15 +365,15 @@ fmt.Println("v2 Encoder:\n" + string(buf.Bytes()))
// Output: // Output:
// v1: // v1:
// //
// [table] // [table]
// key = "value" // key = "value"
// //
// v2: // v2:
// [table] // [table]
// key = 'value' // key = 'value'
// //
// //
// v2 Encoder: // v2 Encoder:
// [table] // [table]
// key = 'value' // key = 'value'
+77 -6
View File
@@ -42,6 +42,9 @@ benchmark [OPTIONS...] [BRANCH]
-a Compare benchmarks of HEAD against go-toml v1 and -a Compare benchmarks of HEAD against go-toml v1 and
BurntSushi/toml. BurntSushi/toml.
-html When used with -a, emits the output as HTML, ready to be
embedded in the README.
coverage [OPTIONS...] [BRANCH] coverage [OPTIONS...] [BRANCH]
Generates code coverage. Generates code coverage.
@@ -150,16 +153,78 @@ bench() {
fi fi
} }
fmktemp() {
if mktemp --version|grep GNU >/dev/null; then
mktemp --suffix=-$1;
else
mktemp -t $1;
fi
}
benchstathtml() {
python3 - $1 <<'EOF'
import sys
lines = []
stop = False
with open(sys.argv[1]) as f:
for line in f.readlines():
line = line.strip()
if line == "":
stop = True
if not stop:
lines.append(line.split(','))
results = []
for line in reversed(lines[1:]):
v2 = float(line[1])
results.append([
line[0].replace("-32", ""),
"%.1fx" % (float(line[3])/v2), # v1
"%.1fx" % (float(line[5])/v2), # bs
])
# move geomean to the end
results.append(results[0])
del results[0]
def printtable(data):
print("""
<table>
<thead>
<tr><th>Benchmark</th><th>go-toml v1</th><th>BurntSushi/toml</th></tr>
</thead>
<tbody>""")
for r in data:
print(" <tr><td>{}</td><td>{}</td><td>{}</td></tr>".format(*r))
print(""" </tbody>
</table>""")
fold = 3
printtable(results[:fold])
print("<details><summary>See more</summary>")
print('<p>The table above has the results of the most common use-cases. The table below contains the results of all benchmarks, including unrealistic ones. is provided for completeness.</p>')
printtable(results[fold:])
print('<p>This table can be generated with <code>./ci.sh benchmark -a -html</code>.</p>')
print("</details>")
EOF
}
benchmark() { benchmark() {
case "$1" in case "$1" in
-d) -d)
shift shift
target="${1?Need to provide a target branch argument}" target="${1?Need to provide a target branch argument}"
old=`mktemp --suffix=-${target}` old=`fmktemp ${target}`
bench "${target}" "${old}" bench "${target}" "${old}"
new=`mktemp --suffix=-HEAD` new=`fmktemp HEAD`
bench HEAD "${new}" bench HEAD "${new}"
benchstat "${old}" "${new}" benchstat "${old}" "${new}"
@@ -168,18 +233,24 @@ benchmark() {
-a) -a)
shift shift
v2stats=`mktemp -t go-toml-v2` v2stats=`fmktemp go-toml-v2`
bench HEAD "${v2stats}" "github.com/pelletier/go-toml/v2" bench HEAD "${v2stats}" "github.com/pelletier/go-toml/v2"
v1stats=`mktemp -t go-toml-v1` v1stats=`fmktemp go-toml-v1`
bench HEAD "${v1stats}" "github.com/pelletier/go-toml" bench HEAD "${v1stats}" "github.com/pelletier/go-toml"
bsstats=`mktemp -t bs-toml` bsstats=`fmktemp bs-toml`
bench HEAD "${bsstats}" "github.com/BurntSushi/toml" bench HEAD "${bsstats}" "github.com/BurntSushi/toml"
cp "${v2stats}" go-toml-v2.txt cp "${v2stats}" go-toml-v2.txt
cp "${v1stats}" go-toml-v1.txt cp "${v1stats}" go-toml-v1.txt
cp "${bsstats}" bs-toml.txt cp "${bsstats}" bs-toml.txt
benchstat -geomean go-toml-v2.txt go-toml-v1.txt bs-toml.txt if [ "$1" = "-html" ]; then
tmpcsv=`fmktemp csv`
benchstat -csv -geomean go-toml-v2.txt go-toml-v1.txt bs-toml.txt > $tmpcsv
benchstathtml $tmpcsv
else
benchstat -geomean go-toml-v2.txt go-toml-v1.txt bs-toml.txt
fi
rm -f go-toml-v2.txt go-toml-v1.txt bs-toml.txt rm -f go-toml-v2.txt go-toml-v1.txt bs-toml.txt
return $? return $?