From 4b7f7b349e906e4760279273f1c03ad5fa802e25 Mon Sep 17 00:00:00 2001 From: Charlie Stanton Date: Fri, 21 Apr 2023 14:25:08 +0100 Subject: Improves performance by being more explicit about memory allocation in walk.go --- walk/walk.go | 61 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/walk/walk.go b/walk/walk.go index 48aff34..6d00ef2 100644 --- a/walk/walk.go +++ b/walk/walk.go @@ -65,7 +65,6 @@ func (value TerminalValue) String() string { panic("Unknown TerminalValue") } } -func (value TerminalValue) atomness() {} type ValueNull struct {} func (value ValueNull) Atomise() []Atom { @@ -74,7 +73,6 @@ func (value ValueNull) Atomise() []Atom { func (value ValueNull) String() string { return "null" } -func (value ValueNull) atomness() {} type ValueBool bool func (value ValueBool) Atomise() []Atom { @@ -87,7 +85,6 @@ func (value ValueBool) String() string { return "false" } } -func (value ValueBool) atomness() {} type ValueNumber float64 func (value ValueNumber) Atomise() []Atom { @@ -97,13 +94,16 @@ func (value ValueNumber) String() string { v := float64(value) return fmt.Sprintf("%f", v) } -func (value ValueNumber) atomness() {} type StringTerminal struct {} -func (value StringTerminal) atomness() {} +func (value StringTerminal) String() string { + return "\"" +} type StringAtom rune -func (value StringAtom) atomness() {} +func (value StringAtom) String() string { + return string(value) +} type ValueString string func (value ValueString) Atomise() (out []Atom) { @@ -119,8 +119,7 @@ func (value ValueString) String() string { } type Atom interface { - // Something so the compiler will check that only certain types are being cast into Atoms - atomness() + String() string } type WalkValue interface { @@ -421,10 +420,14 @@ func JsonOut(in chan WalkItem) { } func ConcatData(first []Atom, second []Atom) []Atom { - return append(append([]Atom(nil), first...), second...) + res := make([]Atom, 0, len(first) + len(second)) + res = append(res, first...) + res = append(res, second...) + return res } func Atomise(in []WalkValue) (out []Atom) { + out = make([]Atom, 0, len(in) * 2) for _, value := range in { out = append(out, value.Atomise()...) } @@ -461,7 +464,24 @@ type CompoundResult struct { } func Compound(in []Atom) (out []WalkValue, error error) { + numValues := 0 i := 0 + inString := false + for _, atom := range in { + switch atom.(type) { + case TerminalValue, ValueNull, ValueBool, ValueNumber: + if !inString { + numValues++ + } + case StringTerminal: + if inString { + numValues++ + } + inString = !inString + } + } + i = 0 + out = make([]WalkValue, 0, numValues) for { if i >= len(in) { break @@ -469,17 +489,8 @@ func Compound(in []Atom) (out []WalkValue, error error) { atom := in[i] i++ switch v := atom.(type) { - case TerminalValue: - out = append(out, v) - continue - case ValueNull: - out = append(out, v) - continue - case ValueBool: - out = append(out, v) - continue - case ValueNumber: - out = append(out, v) + case TerminalValue, ValueNull, ValueBool, ValueNumber: + out = append(out, v.(WalkValue)) continue case StringAtom: return nil, CompoundRuneOutsideString @@ -498,15 +509,7 @@ func Compound(in []Atom) (out []WalkValue, error error) { switch v := atom.(type) { case StringTerminal: break loop - case StringAtom: - builder.WriteRune(rune(v)) - case ValueNull: - builder.WriteString(v.String()) - case ValueBool: - builder.WriteString(v.String()) - case ValueNumber: - builder.WriteString(v.String()) - case TerminalValue: + case StringAtom, ValueNull, ValueBool, ValueNumber, TerminalValue: builder.WriteString(v.String()) default: return nil, CompoundInvalidStringAtom -- cgit v1.2.3