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) {
|
||||
arr, err := i.getArray(arrv)
|
||||
if err != nil {
|
||||
@ -1636,6 +1698,8 @@ var funcBuiltins = buildBuiltinMap([]builtin{
|
||||
&binaryBuiltin{name: "join", function: builtinJoin, params: ast.Identifiers{"sep", "arr"}},
|
||||
&unaryBuiltin{name: "reverse", function: builtinReverse, params: ast.Identifiers{"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: "primitiveEquals", function: primitiveEquals, params: ast.Identifiers{"x", "y"}},
|
||||
&binaryBuiltin{name: "equals", function: builtinEquals, params: ast.Identifiers{"x", "y"}},
|
||||
|
Loading…
x
Reference in New Issue
Block a user