mirror of
https://github.com/google/go-jsonnet.git
synced 2025-09-29 09:21:03 +02:00
perf: use native builtin for foldl
and foldr
benchmark old ns/op new ns/op delta Benchmark_Builtin_substr-8 17914126 16328579 -8.85% Benchmark_Builtin_reverse-8 360776847 346691957 -3.90% Benchmark_Builtin_parseInt-8 8686867 8314151 -4.29% Benchmark_Builtin_base64Decode-8 22157223 21749268 -1.84% Benchmark_Builtin_base64DecodeBytes-8 281975629 281841745 -0.05% Benchmark_Builtin_base64-8 23824149 23716470 -0.45% Benchmark_Builtin_base64_byte_array-8 141846327 141377054 -0.33% Benchmark_Builtin_manifestJsonEx-8 9317781 9279067 -0.42% Benchmark_Builtin_comparison-8 128783954 128362069 -0.33% Benchmark_Builtin_comparison2-8 2082396660 2029123362 -2.56% Benchmark_Builtin_foldl-8 159908963 31278937 -80.44%
This commit is contained in:
parent
953327b03c
commit
e9a59202cf
64
builtins.go
64
builtins.go
@ -396,6 +396,68 @@ func builtinJoin(i *interpreter, sep, arrv value) (value, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func builtinFoldl(i *interpreter, funcv, arrv, initv value) (value, error) {
|
||||||
|
fun, err := i.getFunction(funcv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var len int
|
||||||
|
var elements []*cachedThunk
|
||||||
|
switch arrType := arrv.(type) {
|
||||||
|
case valueString:
|
||||||
|
len = arrType.length()
|
||||||
|
for _, item := range arrType.getRunes() {
|
||||||
|
elements = append(elements, readyThunk(makeStringFromRunes([]rune{item})))
|
||||||
|
}
|
||||||
|
case *valueArray:
|
||||||
|
len = arrType.length()
|
||||||
|
elements = arrType.elements
|
||||||
|
default:
|
||||||
|
return nil, i.Error("foldl second parameter should be string or array, got " + arrType.getType().name)
|
||||||
|
}
|
||||||
|
|
||||||
|
accValue := initv
|
||||||
|
for counter := 0; counter < len; counter++ {
|
||||||
|
accValue, err = fun.call(i, args([]*cachedThunk{readyThunk(accValue), elements[counter]}...))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return accValue, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func builtinFoldr(i *interpreter, funcv, arrv, initv value) (value, error) {
|
||||||
|
fun, err := i.getFunction(funcv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var len int
|
||||||
|
var elements []*cachedThunk
|
||||||
|
switch arrType := arrv.(type) {
|
||||||
|
case valueString:
|
||||||
|
len = arrType.length()
|
||||||
|
for _, item := range arrType.getRunes() {
|
||||||
|
elements = append(elements, readyThunk(makeStringFromRunes([]rune{item})))
|
||||||
|
}
|
||||||
|
case *valueArray:
|
||||||
|
len = arrType.length()
|
||||||
|
elements = arrType.elements
|
||||||
|
default:
|
||||||
|
return nil, i.Error("foldr second parameter should be string or array, got " + arrType.getType().name)
|
||||||
|
}
|
||||||
|
|
||||||
|
accValue := initv
|
||||||
|
for counter := len - 1; counter >= 0; counter-- {
|
||||||
|
accValue, err = fun.call(i, args([]*cachedThunk{elements[counter], readyThunk(accValue)}...))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return accValue, nil
|
||||||
|
}
|
||||||
|
|
||||||
func builtinReverse(i *interpreter, arrv value) (value, error) {
|
func builtinReverse(i *interpreter, arrv value) (value, error) {
|
||||||
arr, err := i.getArray(arrv)
|
arr, err := i.getArray(arrv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1636,6 +1698,8 @@ var funcBuiltins = buildBuiltinMap([]builtin{
|
|||||||
&binaryBuiltin{name: "join", function: builtinJoin, params: ast.Identifiers{"sep", "arr"}},
|
&binaryBuiltin{name: "join", function: builtinJoin, params: ast.Identifiers{"sep", "arr"}},
|
||||||
&unaryBuiltin{name: "reverse", function: builtinReverse, params: ast.Identifiers{"arr"}},
|
&unaryBuiltin{name: "reverse", function: builtinReverse, params: ast.Identifiers{"arr"}},
|
||||||
&binaryBuiltin{name: "filter", function: builtinFilter, params: ast.Identifiers{"func", "arr"}},
|
&binaryBuiltin{name: "filter", function: builtinFilter, params: ast.Identifiers{"func", "arr"}},
|
||||||
|
&ternaryBuiltin{name: "foldl", function: builtinFoldl, params: ast.Identifiers{"func", "arr", "init"}},
|
||||||
|
&ternaryBuiltin{name: "foldr", function: builtinFoldr, params: ast.Identifiers{"func", "arr", "init"}},
|
||||||
&binaryBuiltin{name: "range", function: builtinRange, params: ast.Identifiers{"from", "to"}},
|
&binaryBuiltin{name: "range", function: builtinRange, params: ast.Identifiers{"from", "to"}},
|
||||||
&binaryBuiltin{name: "primitiveEquals", function: primitiveEquals, params: ast.Identifiers{"x", "y"}},
|
&binaryBuiltin{name: "primitiveEquals", function: primitiveEquals, params: ast.Identifiers{"x", "y"}},
|
||||||
&binaryBuiltin{name: "equals", function: builtinEquals, params: ast.Identifiers{"x", "y"}},
|
&binaryBuiltin{name: "equals", function: builtinEquals, params: ast.Identifiers{"x", "y"}},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user