From 5d8582711936cae3c42f2645d0f304418b17fb7e Mon Sep 17 00:00:00 2001 From: Charlie Stanton Date: Fri, 21 Apr 2023 15:31:00 +0100 Subject: Replace implementation of Atomise to improve performance --- walk/walk.go | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/walk/walk.go b/walk/walk.go index 6d00ef2..490a6f2 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -6,6 +6,7 @@ import ( "fmt" "strings" "math" + "unicode/utf8" ) // int or string @@ -48,8 +49,8 @@ const ( MapBegin MapEnd ) -func (value TerminalValue) Atomise() []Atom { - return []Atom{value} +func (value TerminalValue) Atomise(in []Atom) []Atom { + return append(in, value) } func (value TerminalValue) String() string { switch value { @@ -67,16 +68,16 @@ func (value TerminalValue) String() string { } type ValueNull struct {} -func (value ValueNull) Atomise() []Atom { - return []Atom{ValueNull{}} +func (value ValueNull) Atomise(in []Atom) []Atom { + return append(in, value) } func (value ValueNull) String() string { return "null" } type ValueBool bool -func (value ValueBool) Atomise() []Atom { - return []Atom{value} +func (value ValueBool) Atomise(in []Atom) []Atom { + return append(in, value) } func (value ValueBool) String() string { if value { @@ -87,8 +88,8 @@ func (value ValueBool) String() string { } type ValueNumber float64 -func (value ValueNumber) Atomise() []Atom { - return []Atom{value} +func (value ValueNumber) Atomise(in []Atom) []Atom { + return append(in, value) } func (value ValueNumber) String() string { v := float64(value) @@ -106,13 +107,13 @@ func (value StringAtom) String() string { } type ValueString string -func (value ValueString) Atomise() (out []Atom) { - out = append(out, StringTerminal{}) +func (value ValueString) Atomise(in []Atom) []Atom { + in = append(in, StringTerminal{}) for _, char := range value { - out = append(out, StringAtom(char)) + in = append(in, StringAtom(char)) } - out = append(out, StringTerminal{}) - return out + in = append(in, StringTerminal{}) + return in } func (value ValueString) String() string { return fmt.Sprintf("\"%s\"", string(value)) @@ -123,7 +124,8 @@ type Atom interface { } type WalkValue interface { - Atomise() []Atom + // Append this values atoms to the input + Atomise(in []Atom) []Atom String() string } @@ -427,9 +429,20 @@ func ConcatData(first []Atom, second []Atom) []Atom { } func Atomise(in []WalkValue) (out []Atom) { - out = make([]Atom, 0, len(in) * 2) + numAtoms := 0 + for _, value := range in { + switch v := value.(type) { + case TerminalValue, ValueNull, ValueBool, ValueNumber: + numAtoms++ + case ValueString: + numAtoms += utf8.RuneCountInString(string(v)) + 2 + default: + panic("Invalid WalkValue") + } + } + out = make([]Atom, 0, numAtoms) for _, value := range in { - out = append(out, value.Atomise()...) + out = value.Atomise(out) } return out } -- cgit v1.2.3