Skip to content

Commit 7eb8e4d

Browse files
committed
Add benchmarks
1 parent 41eb134 commit 7eb8e4d

File tree

1 file changed

+61
-3
lines changed

1 file changed

+61
-3
lines changed

server/runtime_javascript_test.go

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
package server
1616

1717
import (
18-
"strings"
19-
"testing"
20-
18+
"encoding/json"
2119
"github.com/dop251/goja"
2220
"go.uber.org/zap"
2321
"go.uber.org/zap/zaptest/observer"
22+
"strings"
23+
"testing"
2424
)
2525

2626
func TestJsObjectFreeze(t *testing.T) {
@@ -112,3 +112,61 @@ m.get('a');
112112
}
113113
})
114114
}
115+
116+
const data = `{"title_data":{"ads_config": [1,2,3]}}`
117+
118+
// go test -run=XXX -bench=BenchmarkParse ./...
119+
// go test -run=XXX -bench=BenchmarkParse ./... -benchmem
120+
func BenchmarkParseJsonGo(b *testing.B) {
121+
vm := goja.New()
122+
b.ResetTimer()
123+
for i := 0; i < b.N; i++ {
124+
v, err := jsJsonParse(vm, data)
125+
if err != nil {
126+
b.Fatal(err)
127+
}
128+
vm.Set("data", v)
129+
vm.RunString(`data.foo = []; data.foo.push(3)`)
130+
}
131+
}
132+
func BenchmarkParseJsonGoja(b *testing.B) {
133+
vm := goja.New()
134+
b.ResetTimer()
135+
for i := 0; i < b.N; i++ {
136+
var out map[string]any
137+
if err := json.Unmarshal([]byte(data), &out); err != nil {
138+
b.Fatal(err)
139+
}
140+
pointerizeSlices(out)
141+
vm.Set("data", out)
142+
vm.RunString(`data.foo = []; data.foo.push(3)`)
143+
}
144+
}
145+
146+
// pointerizeSlices recursively walks a map[string]interface{} and replaces any []interface{} references for *[]interface{}.
147+
// This is needed to allow goja operations that resize a JS wrapped Go slice to work as expected, otherwise
148+
// such operations won't reflect on the original slice as it would be passed by value and not by reference.
149+
func pointerizeSlices(m interface{}) {
150+
switch i := m.(type) {
151+
case map[string]interface{}:
152+
for k, v := range i {
153+
if s, ok := v.([]interface{}); ok {
154+
i[k] = &s
155+
pointerizeSlices(&s)
156+
}
157+
if mi, ok := v.(map[string]interface{}); ok {
158+
pointerizeSlices(mi)
159+
}
160+
}
161+
case *[]interface{}:
162+
for idx, v := range *i {
163+
if s, ok := v.([]interface{}); ok {
164+
(*i)[idx] = &s
165+
pointerizeSlices(&s)
166+
}
167+
if mi, ok := v.(map[string]interface{}); ok {
168+
pointerizeSlices(mi)
169+
}
170+
}
171+
}
172+
}

0 commit comments

Comments
 (0)