<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/walk
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2023-04-24 19:02:23 +0100
committerCharlie Stanton <charlie@shtanton.xyz>2023-04-24 19:02:23 +0100
commit1e092ec62cf591e57f0b0bfb80b4484dd90c9c8c (patch)
tree38ef5e079cacdb860a12f92cd9921246d1be106c /walk
parent8e80185508a697ddfcfed4a04d3f4e1ac5a330a9 (diff)
downloadstred-go-1e092ec62cf591e57f0b0bfb80b4484dd90c9c8c.tar
Improves performance of reading JSON strings
Diffstat (limited to 'walk')
-rw-r--r--walk/walk.go81
1 files changed, 39 insertions, 42 deletions
diff --git a/walk/walk.go b/walk/walk.go
index 008713b..0719d1c 100644
--- a/walk/walk.go
+++ b/walk/walk.go
@@ -228,7 +228,7 @@ type JSONIn struct {
func NewJSONIn(reader *bufio.Reader) JSONIn {
return JSONIn {
- path: nil,
+ path: make([]Atom, 0, 256),
reader: reader,
structure: []JSONInStructure{JSONInRoot},
}
@@ -297,6 +297,41 @@ func (in *JSONIn) require(criterion rune) {
}
}
+func (in *JSONIn) readString(out []Atom) []Atom {
+ // TODO: improve
+ out = append(out, NewAtomStringTerminal())
+ for {
+ r, _, err := in.reader.ReadRune()
+ if err != nil {
+ panic("Missing closing terminal in string input: " + err.Error())
+ }
+ if r == '"' {
+ break
+ }
+ if r == '\\' {
+ r, _, err = in.reader.ReadRune()
+ if err != nil {
+ panic("Missing rune after \\")
+ }
+ if len(out) == cap(out) {
+ newOut := make([]Atom, len(out), cap(out) * 2)
+ copy(newOut, out)
+ out = newOut
+ }
+ out = append(out, NewAtomStringRune(r))
+ continue
+ }
+ if len(out) == cap(out) {
+ newOut := make([]Atom, len(out), cap(out) * 2)
+ copy(newOut, out)
+ out = newOut
+ }
+ out = append(out, NewAtomStringRune(r))
+ }
+ out = append(out, NewAtomStringTerminal())
+ return out
+}
+
func (in *JSONIn) Read() (WalkItem, error) {
item, err := in.read()
if err != nil {
@@ -331,26 +366,7 @@ func (in *JSONIn) read() (WalkItem, error) {
if r != '"' {
panic("Expected key, found something else")
}
- in.path = append(in.path, NewAtomStringTerminal())
- for {
- r, _, err = in.reader.ReadRune()
- if err != nil {
- return WalkItem {}, err
- }
- if r == '"' {
- break
- }
- if r == '\\' {
- r, _, err = in.reader.ReadRune()
- if err != nil {
- panic("Missing rune after \\")
- }
- in.path = append(in.path, NewAtomStringRune(r))
- continue
- }
- in.path = append(in.path, NewAtomStringRune(r))
- }
- in.path = append(in.path, NewAtomStringTerminal())
+ in.path = in.readString(in.path)
r, err = in.nextNonWsRune()
if err != nil {
panic("Expected : got: " + err.Error())
@@ -432,27 +448,8 @@ func (in *JSONIn) read() (WalkItem, error) {
Path: in.path,
}, nil
case '"':
- value := make([]Atom, 0, 2)
- value = append(value, NewAtomStringTerminal())
- for {
- r, _, err = in.reader.ReadRune()
- if err != nil {
- panic("Missing closing terminal in string input: " + err.Error())
- }
- if r == '"' {
- break
- }
- if r == '\\' {
- r, _, err = in.reader.ReadRune()
- if err != nil {
- panic("Missing rune after \\")
- }
- value = append(value, NewAtomStringRune(r))
- continue
- }
- value = append(value, NewAtomStringRune(r))
- }
- value = append(value, NewAtomStringTerminal())
+ value := make([]Atom, 0, 64)
+ value = in.readString(value)
in.structure = append(in.structure, JSONInValueEnd)
return WalkItem {
Value: value,