<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/walk
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2023-04-21 12:51:25 +0100
committerCharlie Stanton <charlie@shtanton.xyz>2023-04-21 12:51:25 +0100
commit26bce7119200f37f8b9f3ddc1a2c76c85f7c88be (patch)
tree21a2aa762215e2230ba676454828c1497a568cc6 /walk
parent184118c1522ee4e78a0588fcac8eb235f512b599 (diff)
downloadstred-go-26bce7119200f37f8b9f3ddc1a2c76c85f7c88be.tar
Changes the implementation of Atomise and Compound to no longer use goroutines
This results in a massive performance boost, ~4x speedup
Diffstat (limited to 'walk')
-rw-r--r--walk/walk.go167
1 files changed, 63 insertions, 104 deletions
diff --git a/walk/walk.go b/walk/walk.go
index 5c1ca75..48aff34 100644
--- a/walk/walk.go
+++ b/walk/walk.go
@@ -48,8 +48,8 @@ const (
MapBegin
MapEnd
)
-func (value TerminalValue) Pieces(out chan<- Atom) {
- out<-value
+func (value TerminalValue) Atomise() []Atom {
+ return []Atom{value}
}
func (value TerminalValue) String() string {
switch value {
@@ -68,8 +68,8 @@ func (value TerminalValue) String() string {
func (value TerminalValue) atomness() {}
type ValueNull struct {}
-func (value ValueNull) Pieces(out chan<- Atom) {
- out<-value
+func (value ValueNull) Atomise() []Atom {
+ return []Atom{ValueNull{}}
}
func (value ValueNull) String() string {
return "null"
@@ -77,8 +77,8 @@ func (value ValueNull) String() string {
func (value ValueNull) atomness() {}
type ValueBool bool
-func (value ValueBool) Pieces(out chan<- Atom) {
- out<-value
+func (value ValueBool) Atomise() []Atom {
+ return []Atom{value}
}
func (value ValueBool) String() string {
if value {
@@ -90,8 +90,8 @@ func (value ValueBool) String() string {
func (value ValueBool) atomness() {}
type ValueNumber float64
-func (value ValueNumber) Pieces(out chan<- Atom) {
- out<-value
+func (value ValueNumber) Atomise() []Atom {
+ return []Atom{value}
}
func (value ValueNumber) String() string {
v := float64(value)
@@ -106,12 +106,13 @@ type StringAtom rune
func (value StringAtom) atomness() {}
type ValueString string
-func (value ValueString) Pieces(out chan<- Atom) {
- out<-StringTerminal{}
+func (value ValueString) Atomise() (out []Atom) {
+ out = append(out, StringTerminal{})
for _, char := range value {
- out<-StringAtom(char)
+ out = append(out, StringAtom(char))
}
- out<-StringTerminal{}
+ out = append(out, StringTerminal{})
+ return out
}
func (value ValueString) String() string {
return fmt.Sprintf("\"%s\"", string(value))
@@ -123,7 +124,7 @@ type Atom interface {
}
type WalkValue interface {
- Pieces(out chan<- Atom)
+ Atomise() []Atom
String() string
}
@@ -423,28 +424,9 @@ func ConcatData(first []Atom, second []Atom) []Atom {
return append(append([]Atom(nil), first...), second...)
}
-func Atomise(in <-chan WalkValue) <-chan Atom {
- out := make(chan Atom)
- go func(out chan<- Atom, input <-chan WalkValue) {
- for value := range input {
- value.Pieces(out)
- }
- close(out)
- }(out, in)
- return out
-}
-
-func MemoryAtomise(in []WalkValue) (out []Atom) {
- inChan := make(chan WalkValue)
- go func(in []WalkValue, out chan<- WalkValue) {
- for _, value := range in {
- out<-value
- }
- close(out)
- }(in, inChan)
- outChan := Atomise(inChan)
- for atom := range outChan {
- out = append(out, atom)
+func Atomise(in []WalkValue) (out []Atom) {
+ for _, value := range in {
+ out = append(out, value.Atomise()...)
}
return out
}
@@ -478,82 +460,59 @@ type CompoundResult struct {
error error
}
-func Compound(in <-chan Atom) <-chan CompoundResult {
- out := make(chan CompoundResult)
- go func(out chan<- CompoundResult, in <-chan Atom) {
- outer: for {
- atom, hasAtom := <-in
- if !hasAtom {
- break
+func Compound(in []Atom) (out []WalkValue, error error) {
+ i := 0
+ for {
+ if i >= len(in) {
+ break
+ }
+ 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)
+ continue
+ case StringAtom:
+ return nil, CompoundRuneOutsideString
+ case StringTerminal:
+ default:
+ return nil, CompoundUnknownAtom
+ }
+ // Handle string start
+ var builder strings.Builder
+ loop: for {
+ if i >= len(in) {
+ return nil, CompoundMissingEnd
}
+ atom := in[i]
+ i++
switch v := atom.(type) {
- case TerminalValue:
- out<-CompoundResult{v, nil}
- continue
+ case StringTerminal:
+ break loop
+ case StringAtom:
+ builder.WriteRune(rune(v))
case ValueNull:
- out<-CompoundResult{v, nil}
- continue
+ builder.WriteString(v.String())
case ValueBool:
- out<-CompoundResult{v, nil}
- continue
+ builder.WriteString(v.String())
case ValueNumber:
- out<-CompoundResult{v, nil}
- continue
- case StringAtom:
- out<-CompoundResult{nil, CompoundRuneOutsideString}
- break outer
- case StringTerminal:
+ builder.WriteString(v.String())
+ case TerminalValue:
+ builder.WriteString(v.String())
default:
- out<-CompoundResult{nil, CompoundUnknownAtom}
- break outer
- }
- // Handle string start
- var builder strings.Builder
- loop: for {
- atom, hasAtom := <-in
- if !hasAtom {
- out<-CompoundResult{nil, CompoundMissingEnd}
- break outer
- }
- 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:
- builder.WriteString(v.String())
- default:
- out<-CompoundResult{nil, CompoundInvalidStringAtom}
- break outer
- }
+ return nil, CompoundInvalidStringAtom
}
- out<-CompoundResult{ValueString(builder.String()), nil}
}
- close(out)
- }(out, in)
- return out
-}
-
-func MemoryCompound(in []Atom) (out []WalkValue, err error) {
- inChan := make(chan Atom)
- go func(in []Atom, out chan<- Atom) {
- for _, atom := range in {
- out<-atom
- }
- close(out)
- }(in, inChan)
- outChan := Compound(inChan)
- for result := range outChan {
- if result.error != nil {
- return out, result.error
- }
- out = append(out, result.value)
+ out = append(out, ValueString(builder.String()))
}
return out, nil
-} \ No newline at end of file
+}