Skip to content

Commit 2eac4e5

Browse files
authored
Merge pull request #1 from bhmj/memory-optimization-v1
- Zero memory consumption on evaluation (preallocated on parse time)- - Minor speed optimization - infinity comparison improved - invalid hex number detection - test coverage report added
2 parents 51d08f3 + 6b6b6cb commit 2eac4e5

11 files changed

Lines changed: 222 additions & 94 deletions

File tree

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"mode": "auto",
1212
"program": "${workspaceFolder}/cmd/xpression/main.go",
1313
"env": {},
14-
"args": ["@.price>10"]
14+
"args": ["0xDEFG + 1"]
1515
}
1616
]
1717
}

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ help:
1212
echo ""
1313
echo " <command> is"
1414
echo ""
15-
echo " configure - install tools and dependencies"
15+
echo " configure - install tools and dependencies (gocyclo and golangci-lint)"
1616
echo " build - build jsonslice CLI"
1717
echo " run - run jsonslice CLI"
1818
echo " lint - run linters"
1919
echo " test - run tests"
20+
echo " cover - generate coverage report"
21+
echo ""
2022

2123
configure:
2224
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
@@ -38,6 +40,10 @@ test:
3840
go test -cover ./...
3941
go test -benchmem -bench=.
4042

43+
cover:
44+
go test -coverprofile=coverage.out ./...
45+
go tool cover -html=coverage.out
46+
4147
.PHONY: all configure help build run lint test
4248

4349
$(V).SILENT:

README.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@ Expression examples:
4242
4343
// external data in expression (aka variables)
4444
foobar := 123
45-
varFunc := func(name []byte) (*xpression.Operand, error) {
45+
varFunc := func(name []byte, result *xpression.Operator) error {
4646
mapper := map[string]*int{
4747
`foobar`: &foobar
4848
}
49-
return xpression.Number(float64(*mapper[string(name)])), nil
49+
xpression.SetNumber(float64(*mapper[string(name)]))
50+
return nil
5051
}
5152
tokens, err := xpression.Parse([]byte(`27 / foobar`))
5253
result, err := xpression.Evaluate(tokens, varFunc)
@@ -81,35 +82,36 @@ Tests cover the majority of cases described in ECMAScript Language definition (s
8182

8283
Evaluate `(2) + (2) == (4)`
8384

84-
```diff
85+
```golang
8586
$ go test -bench=. -benchmem -benchtime=4s
8687
goos: darwin
8788
goarch: amd64
8889
pkg: github.com/bhmj/xpression
8990
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
90-
Benchmark_ModifiedNumericLiteral_WithParsing-16 2714204 1853 ns/op 1272 B/op 26 allocs/op
91-
Benchmark_ModifiedNumericLiteral_WithoutParsing-16 31129712 143.9 ns/op 128 B/op 2 allocs/op
91+
Benchmark_ModifiedNumericLiteral_WithParsing-16 2622770 1811 ns/op 1272 B/op 26 allocs/op
92+
Benchmark_ModifiedNumericLiteral_WithoutParsing-16 77455698 57.55 ns/op 0 B/op 0 allocs/op
9293
PASS
93-
ok github.com/bhmj/xpression 12.363s
94+
ok github.com/bhmj/xpression 11.548s
9495
```
9596

9697
The same expression evaluated with [github.com/Knetic/govaluate](https://github.com/Knetic/govaluate) :
9798

98-
```diff
99+
```golang
99100
$ go test -bench='LiteralModifiers' -benchmem -benchtime=4s
100101
goos: darwin
101102
goarch: amd64
102103
pkg: github.com/Knetic/govaluate
103104
cpu: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
104-
BenchmarkEvaluationLiteralModifiers_WithParsing-16 1000000 4019 ns/op 2208 B/op 43 allocs/op
105-
BenchmarkEvaluationLiteralModifiers-16 30173640 147.2 ns/op 8 B/op 1 allocs/op
105+
BenchmarkEvaluationLiteralModifiers_WithParsing-16 1000000 4019 ns/op 2208 B/op 43 allocs/op
106+
BenchmarkEvaluationLiteralModifiers-16 30173640 147.2 ns/op 8 B/op 1 allocs/op
106107
PASS
107108
ok github.com/Knetic/govaluate 9.810s
108109
```
109110

110111

111112
## Changelog
112113

114+
**0.9.0** (2021-11-19) -- Memory allocation reduced. Speed optimization.
113115
**0.8.0** (2021-11-11) -- hex numbers support. Production ready.
114116
**0.7.x** (2021-11-11) -- WIP
115117
**0.7.0** (2021-11-10) -- project renamed to `xpression`
@@ -131,7 +133,7 @@ ok github.com/Knetic/govaluate 9.810s
131133
- [x] parser test coverage
132134
- [x] evaluator test coverage
133135
- [x] add external reference type (node reference in jsonslice)
134-
- [ ] optimize memory allocations
136+
- [x] optimize memory allocations
135137
- [ ] Unicode support!
136138

137139
## Contributing

cmd/xpression/main.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ func main() {
3030
}
3131
}
3232

33-
func variableGetter(variable []byte) (*xpression.Operand, error) {
33+
func variableGetter(variable []byte, result *xpression.Operand) error {
3434
if string(variable) == "@.foobar" {
35-
return xpression.Number(123), nil
35+
result.SetNumber(123)
36+
return nil
3637
}
37-
return xpression.Boolean(false), nil
38+
result.SetBoolean(false)
39+
return nil
3840
}
3941

4042
func printParsedExpression(tokens []*xpression.Token) {

errors.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ var (
77
errUnexpectedEndOfString,
88
errMismatchedParentheses,
99
errNotEnoughArguments,
10+
errInvalidHexadecimal,
1011
errTooLongHexadecimal error
1112
)
1213

@@ -15,5 +16,6 @@ func init() {
1516
errUnexpectedEndOfString = errors.New("unexpected end of string")
1617
errMismatchedParentheses = errors.New("mismatched parentheses")
1718
errNotEnoughArguments = errors.New("not enough arguments")
19+
errInvalidHexadecimal = errors.New("invalid hexadecimal")
1820
errTooLongHexadecimal = errors.New("too long hexadecimal")
1921
}

0 commit comments

Comments
 (0)