Reuse AST storage between top-level expressions
``` Comparing: old: v2-wip/1da2fc7 (2021-03-25 20:38:05 -0400 -0400) run: v2-wip/3f23ab9 (2021-03-25 22:35:06 -0400 -0400) ----------------------------------------------------------- name old time/op new time/op delta UnmarshalSimple/v2-8 700ns ± 3% 705ns ± 2% ~ (p=0.690 n=5+5) UnmarshalSimple/v1-8 3.85µs ± 1% 4.02µs ± 4% +4.19% (p=0.032 n=5+5) UnmarshalSimple/bs-8 2.34µs ± 2% 2.38µs ± 3% ~ (p=0.310 n=5+5) ReferenceFile/v2-8 32.2µs ±13% 23.9µs ± 1% -25.79% (p=0.008 n=5+5) ReferenceFile/v1-8 270µs ± 2% 264µs ± 2% ~ (p=0.095 n=5+5) ReferenceFile/bs-8 291µs ± 0% 294µs ± 0% +0.88% (p=0.008 n=5+5) name old alloc/op new alloc/op delta ReferenceFile/v2-8 37.1kB ± 0% 6.7kB ± 0% -81.91% (p=0.008 n=5+5) ReferenceFile/v1-8 131kB ± 0% 131kB ± 0% ~ (p=0.444 n=5+5) ReferenceFile/bs-8 80.8kB ± 0% 80.8kB ± 0% ~ (p=0.571 n=5+5) name old allocs/op new allocs/op delta ReferenceFile/v2-8 152 ± 0% 148 ± 0% -2.63% (p=0.008 n=5+5) ReferenceFile/v1-8 2.65k ± 0% 2.65k ± 0% ~ (all equal) ReferenceFile/bs-8 1.73k ± 0% 1.73k ± 0% ~ (all equal) ~/s/g/p/g/benchmark$ go test -bench=. goos: linux goarch: amd64 pkg: github.com/pelletier/go-toml/v2/benchmark cpu: Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz BenchmarkUnmarshalSimple/v2-8 1692444 710.7 ns/op BenchmarkUnmarshalSimple/v1-8 307609 3862 ns/op BenchmarkUnmarshalSimple/bs-8 520429 2285 ns/op BenchmarkReferenceFile/v2-8 50395 24006 ns/op 6704 B/op 148 allocs/op BenchmarkReferenceFile/v1-8 4144 264655 ns/op 130567 B/op 2649 allocs/op BenchmarkReferenceFile/bs-8 3969 293635 ns/op 80784 B/op 1729 allocs/op PASS ok github.com/pelletier/go-toml/v2/benchmark 8.143s ```
This commit is contained in:
+23
-21
@@ -1,10 +1,5 @@
|
||||
package ast
|
||||
|
||||
type Builder struct {
|
||||
nodes []Node
|
||||
lastIdx int
|
||||
}
|
||||
|
||||
type Reference struct {
|
||||
idx int
|
||||
set bool
|
||||
@@ -14,22 +9,28 @@ func (r Reference) Valid() bool {
|
||||
return r.set
|
||||
}
|
||||
|
||||
func (b *Builder) Finish() *Root {
|
||||
r := &Root{
|
||||
nodes: b.nodes,
|
||||
}
|
||||
b.nodes = nil
|
||||
type Builder struct {
|
||||
tree Root
|
||||
lastIdx int
|
||||
}
|
||||
|
||||
for i := range r.nodes {
|
||||
r.nodes[i].root = r
|
||||
}
|
||||
func (b *Builder) Tree() *Root {
|
||||
return &b.tree
|
||||
}
|
||||
|
||||
return r
|
||||
func (b *Builder) NodeAt(ref Reference) Node {
|
||||
return b.tree.at(ref.idx)
|
||||
}
|
||||
|
||||
func (b *Builder) Reset() {
|
||||
b.tree.nodes = b.tree.nodes[:0]
|
||||
b.lastIdx = 0
|
||||
}
|
||||
|
||||
func (b *Builder) Push(n Node) Reference {
|
||||
b.lastIdx = len(b.nodes)
|
||||
b.nodes = append(b.nodes, n)
|
||||
n.root = &b.tree
|
||||
b.lastIdx = len(b.tree.nodes)
|
||||
b.tree.nodes = append(b.tree.nodes, n)
|
||||
return Reference{
|
||||
idx: b.lastIdx,
|
||||
set: true,
|
||||
@@ -37,10 +38,11 @@ func (b *Builder) Push(n Node) Reference {
|
||||
}
|
||||
|
||||
func (b *Builder) PushAndChain(n Node) Reference {
|
||||
newIdx := len(b.nodes)
|
||||
b.nodes = append(b.nodes, n)
|
||||
n.root = &b.tree
|
||||
newIdx := len(b.tree.nodes)
|
||||
b.tree.nodes = append(b.tree.nodes, n)
|
||||
if b.lastIdx >= 0 {
|
||||
b.nodes[b.lastIdx].next = newIdx
|
||||
b.tree.nodes[b.lastIdx].next = newIdx
|
||||
}
|
||||
b.lastIdx = newIdx
|
||||
return Reference{
|
||||
@@ -50,9 +52,9 @@ func (b *Builder) PushAndChain(n Node) Reference {
|
||||
}
|
||||
|
||||
func (b *Builder) AttachChild(parent Reference, child Reference) {
|
||||
b.nodes[parent.idx].child = child.idx
|
||||
b.tree.nodes[parent.idx].child = child.idx
|
||||
}
|
||||
|
||||
func (b *Builder) Chain(from Reference, to Reference) {
|
||||
b.nodes[from.idx].next = to.idx
|
||||
b.tree.nodes[from.idx].next = to.idx
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user