Skip to content

Commit

Permalink
fix: improve performance of path parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
blgm committed Jan 11, 2021
1 parent 50ec44e commit 4f4286a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 25 deletions.
18 changes: 8 additions & 10 deletions PERFORMANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ There is a benchmark test which compares using JSONry and `encoding/json` to
marshal and unmarshal the same data. The value of the benchmark is in the
relative performance between the two. In the benchamark test:

- Marshal
- JSONry takes 3 times as long as `encoding/json`
- JSONry allocates 7 times as much memory as `enconding/json`

- Unmarshal
- JSONry takes 13 times as long as `encoding/json`
- JSONry allocates 24 times as much memory as `enconding/json`
- JSONry takes 2.5 times as long as `encoding/json`
- JSONry allocates 6 times as much memory as `enconding/json`

- Marshal
- JSONry takes 11 times as long as `encoding/json`
- JSONry allocates 21 times as much memory as `enconding/json`

The command used to run the benchmark tests is:
```bash
go test -run none -bench . -benchmem -benchtime 10s
```
- Version: `go version go1.14.3 darwin/amd64`
- Command: `go test -run none -bench . -benchmem -benchtime 10s`
41 changes: 26 additions & 15 deletions internal/path/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

const (
omitEmptyToken string = "omitempty"
omitEmptyToken string = ",omitempty"
omitAlwaysToken string = "-"
)

Expand Down Expand Up @@ -76,28 +76,39 @@ func parseTag(tag, defaultName string) (name string, omitempty, omitalways bool)
return defaultName, false, true
}

parts := strings.Split(tag, ",")

if len(parts) >= 1 && len(parts[0]) > 0 {
name = parts[0]
} else {
commaIndex := strings.IndexByte(tag, ',')
switch commaIndex {
case -1:
name = tag
case 0:
name = defaultName
}

if len(parts) >= 2 && parts[1] == omitEmptyToken {
omitempty = true
omitempty = tag == omitEmptyToken
default:
name = tag[0:commaIndex]
omitempty = tag[commaIndex:] == omitEmptyToken
}

return
}

func parseSegments(name string) (s []Segment) {
for _, elem := range strings.Split(name, ".") {
s = append(s, Segment{
Name: strings.TrimRight(elem, "[]"),
List: strings.HasSuffix(elem, "[]"),
})
add := func(elem string) {
if strings.HasSuffix(elem, "[]") {
s = append(s, Segment{Name: elem[:len(elem)-2], List: true})
} else {
s = append(s, Segment{Name: elem})
}
}

start := 0
delim := strings.IndexByte(name, '.')
for delim >= 0 {
add(name[start : start+delim])
start = start + delim + 1
delim = strings.IndexByte(name[start:], '.')
}

add(name[start:])

return
}

0 comments on commit 4f4286a

Please sign in to comment.