mirror of
https://github.com/google/go-jsonnet.git
synced 2025-09-28 08:51:01 +02:00
feat: improve std.reverse performance by 73.39%
Implements std.reverse in native Go, improving performance benchmark old ns/op new ns/op delta Benchmark_Builtin_reverse-16 869191619 231309458 -73.39% part of #111
This commit is contained in:
parent
27b4c60bc7
commit
3b580145f4
5
builtin-benchmarks/reverse.jsonnet
Normal file
5
builtin-benchmarks/reverse.jsonnet
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
foo: [
|
||||
std.reverse(std.range(0, 5000)) for i in std.range(0,100)
|
||||
],
|
||||
}
|
18
builtins.go
18
builtins.go
@ -345,6 +345,23 @@ func builtinJoin(i *interpreter, trace traceElement, sep, arrv value) (value, er
|
||||
}
|
||||
}
|
||||
|
||||
func builtinReverse(i *interpreter, trace traceElement, arrv value) (value, error) {
|
||||
arr, err := i.getArray(arrv, trace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lenArr := len(arr.elements) // lenx holds the original array length
|
||||
reversed_array := make([]*cachedThunk, lenArr) // creates a slice that refer to a new array of length lenx
|
||||
|
||||
for i := 0; i < lenArr; i++ {
|
||||
j := lenArr - (i + 1) // j initially holds (lenx - 1) and decreases to 0 while i initially holds 0 and increase to (lenx - 1)
|
||||
reversed_array[i] = arr.elements[j]
|
||||
}
|
||||
|
||||
return makeValueArray(reversed_array), nil
|
||||
}
|
||||
|
||||
func builtinFilter(i *interpreter, trace traceElement, funcv, arrv value) (value, error) {
|
||||
arr, err := i.getArray(arrv, trace)
|
||||
if err != nil {
|
||||
@ -1271,6 +1288,7 @@ var funcBuiltins = buildBuiltinMap([]builtin{
|
||||
&binaryBuiltin{name: "makeArray", function: builtinMakeArray, parameters: ast.Identifiers{"sz", "func"}},
|
||||
&binaryBuiltin{name: "flatMap", function: builtinFlatMap, parameters: ast.Identifiers{"func", "arr"}},
|
||||
&binaryBuiltin{name: "join", function: builtinJoin, parameters: ast.Identifiers{"sep", "arr"}},
|
||||
&unaryBuiltin{name: "reverse", function: builtinReverse, parameters: ast.Identifiers{"arr"}},
|
||||
&binaryBuiltin{name: "filter", function: builtinFilter, parameters: ast.Identifiers{"func", "arr"}},
|
||||
&binaryBuiltin{name: "range", function: builtinRange, parameters: ast.Identifiers{"from", "to"}},
|
||||
&binaryBuiltin{name: "primitiveEquals", function: primitiveEquals, parameters: ast.Identifiers{"x", "y"}},
|
||||
|
@ -2,6 +2,7 @@ package jsonnet
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
@ -15,9 +16,9 @@ func init() {
|
||||
flag.BoolVar(&outputPassthru, "outputPassthru", false, "Pass stdout/err from jsonnet")
|
||||
}
|
||||
|
||||
func Benchmark_Builtin_substr(b *testing.B) {
|
||||
func RunBenchmark(b *testing.B, name string) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
cmd := exec.Command(jsonnetPath, "./builtin-benchmarks/substr.jsonnet")
|
||||
cmd := exec.Command(jsonnetPath, fmt.Sprintf("./builtin-benchmarks/%s.jsonnet", name))
|
||||
if outputPassthru {
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
@ -29,3 +30,11 @@ func Benchmark_Builtin_substr(b *testing.B) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_Builtin_substr(b *testing.B) {
|
||||
RunBenchmark(b, "substr")
|
||||
}
|
||||
|
||||
func Benchmark_Builtin_reverse(b *testing.B) {
|
||||
RunBenchmark(b, "reverse")
|
||||
}
|
||||
|
4
testdata/builtinReverse.golden
vendored
Normal file
4
testdata/builtinReverse.golden
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[
|
||||
2,
|
||||
1
|
||||
]
|
1
testdata/builtinReverse.jsonnet
vendored
Normal file
1
testdata/builtinReverse.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.reverse([1, 2])
|
1
testdata/builtinReverse_empty.golden
vendored
Normal file
1
testdata/builtinReverse_empty.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
[ ]
|
1
testdata/builtinReverse_empty.jsonnet
vendored
Normal file
1
testdata/builtinReverse_empty.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.reverse([])
|
7
testdata/builtinReverse_many.golden
vendored
Normal file
7
testdata/builtinReverse_many.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
[
|
||||
"tester",
|
||||
"is",
|
||||
"name",
|
||||
"my",
|
||||
"hello"
|
||||
]
|
1
testdata/builtinReverse_many.jsonnet
vendored
Normal file
1
testdata/builtinReverse_many.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.reverse(["hello", "my", "name", "is", "tester"])
|
10
testdata/builtinReverse_not_array.golden
vendored
Normal file
10
testdata/builtinReverse_not_array.golden
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
RUNTIME ERROR: Unexpected type string, expected array
|
||||
-------------------------------------------------
|
||||
testdata/builtinReverse_not_array:1:1-20 builtin function <reverse>
|
||||
|
||||
std.reverse("asdf")
|
||||
|
||||
-------------------------------------------------
|
||||
During evaluation
|
||||
|
||||
|
1
testdata/builtinReverse_not_array.jsonnet
vendored
Normal file
1
testdata/builtinReverse_not_array.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.reverse("asdf")
|
3
testdata/builtinReverse_single.golden
vendored
Normal file
3
testdata/builtinReverse_single.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[
|
||||
"hello"
|
||||
]
|
1
testdata/builtinReverse_single.jsonnet
vendored
Normal file
1
testdata/builtinReverse_single.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.reverse(["hello"])
|
Loading…
x
Reference in New Issue
Block a user