Skip to content

Commit a682629

Browse files
committed
Add fold filter optimizations
1 parent 3406415 commit a682629

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

bench_test.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,36 @@ func Benchmark_expr_reuseVm(b *testing.B) {
6666
}
6767

6868
func Benchmark_filter(b *testing.B) {
69-
params := make(map[string]interface{})
70-
params["max"] = 50
69+
type Item struct {
70+
Value int
71+
}
72+
type Env struct {
73+
Items []Item
74+
}
7175

72-
program, err := expr.Compile(`filter(1..100, {# > max})`, expr.Env(params))
76+
program, err := expr.Compile(`filter(filter(Items, {.Value % 2 == 0}), {.Value % 3 == 0})`, expr.Env(Env{}))
7377
if err != nil {
7478
b.Fatal(err)
7579
}
7680

81+
env := Env{
82+
Items: make([]Item, 100),
83+
}
84+
for i := 1; i <= 100; i++ {
85+
env.Items[i-1] = Item{Value: i}
86+
}
87+
88+
var out interface{}
7789
for n := 0; n < b.N; n++ {
78-
_, err = vm.Run(program, params)
90+
out, err = vm.Run(program, env)
7991
}
8092

8193
if err != nil {
8294
b.Fatal(err)
8395
}
96+
if len(out.([]interface{})) != 16 {
97+
b.Fail()
98+
}
8499
}
85100

86101
func Benchmark_access(b *testing.B) {

optimizer/fold.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,26 @@ func (fold *fold) Exit(node *Node) {
129129
}
130130

131131
}
132+
133+
case *BuiltinNode:
134+
switch n.Name {
135+
case "filter":
136+
if len(n.Arguments) != 2 {
137+
return
138+
}
139+
if base, ok := n.Arguments[0].(*BuiltinNode); ok && base.Name == "filter" {
140+
patch(&BuiltinNode{
141+
Name: "filter",
142+
Arguments: []Node{
143+
base.Arguments[0],
144+
&BinaryNode{
145+
Operator: "&&",
146+
Left: base.Arguments[1],
147+
Right: n.Arguments[1],
148+
},
149+
},
150+
})
151+
}
152+
}
132153
}
133154
}

0 commit comments

Comments
 (0)