<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/walk/walk.go
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2023-04-21 14:25:08 +0100
committerCharlie Stanton <charlie@shtanton.xyz>2023-04-21 14:25:08 +0100
commit4b7f7b349e906e4760279273f1c03ad5fa802e25 (patch)
tree28adb4a77ac97a959b70c9720cc96b36f7b89c78 /walk/walk.go
parent26bce7119200f37f8b9f3ddc1a2c76c85f7c88be (diff)
downloadstred-go-4b7f7b349e906e4760279273f1c03ad5fa802e25.tar
Improves performance by being more explicit about memory allocation in walk.go
Diffstat (limited to 'walk/walk.go')
-rw-r--r--walk/walk.go61
1 files 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