diff options
| author | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-21 12:51:25 +0100 | 
|---|---|---|
| committer | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-21 12:51:25 +0100 | 
| commit | 26bce7119200f37f8b9f3ddc1a2c76c85f7c88be (patch) | |
| tree | 21a2aa762215e2230ba676454828c1497a568cc6 /walk | |
| parent | 184118c1522ee4e78a0588fcac8eb235f512b599 (diff) | |
| download | stred-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.go | 167 | 
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 +} | 
