Skip to content

Commit 21d162c

Browse files
author
Yan-Fa Li
committed
Add a more complex schema benchmark
- Complex schema 1 is based off a request and Complex schema 2 is based off a response schema in real world schema usage - move allocation of byte.Buffer outside of benchmark loop, as we're interested in measuring that. - set Buffer to 512Kb to avoid dynamic schema growth for expected test usage.
1 parent 358e806 commit 21d162c

File tree

2 files changed

+215
-2
lines changed

2 files changed

+215
-2
lines changed
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
package jsonschema_test
2+
3+
import (
4+
"github.com/rs/rest-layer/schema"
5+
"math"
6+
"time"
7+
)
8+
9+
var (
10+
rfc3339NanoDefault = schema.Field{
11+
Description: "UTC start time in RFC3339 format with Nano second support, e.g. 2006-01-02T15:04:05.999999999Z",
12+
Validator: &schema.Time{
13+
TimeLayouts: []string{time.RFC3339Nano},
14+
},
15+
}
16+
)
17+
18+
// Default modifies an existing schema.Field with a default value.
19+
func Default(f schema.Field, v interface{}) schema.Field {
20+
f.Default = v
21+
return f
22+
}
23+
24+
// Required modifies an existing schema.Field to be required.
25+
func Required(s schema.Field) schema.Field {
26+
s.Required = true
27+
return s
28+
}
29+
30+
// RFC3339Nano schema.Field template
31+
func RFC3339Nano() schema.Field {
32+
return rfc3339NanoDefault
33+
}
34+
35+
// String field
36+
func String(min, max int, description string) schema.Field {
37+
return schema.Field{
38+
Description: description,
39+
Default: "",
40+
Validator: &schema.String{
41+
MinLen: min,
42+
MaxLen: max,
43+
},
44+
}
45+
}
46+
47+
// Integer returns schema.Field template for int validation.
48+
func Integer(min, max int, description string) schema.Field {
49+
return schema.Field{
50+
Default: min,
51+
Description: description,
52+
Validator: &schema.Integer{
53+
Boundaries: &schema.Boundaries{
54+
Min: float64(min),
55+
Max: float64(max),
56+
},
57+
},
58+
}
59+
}
60+
61+
// Bool validator helper
62+
func Bool(description string) schema.Field {
63+
return schema.Field{
64+
Description: description,
65+
Validator: &schema.Bool{},
66+
}
67+
}
68+
69+
func getComplexSchema1() schema.Schema {
70+
mSchema := &schema.Schema{
71+
Description: "m",
72+
Fields: schema.Fields{
73+
"ma": String(0, 64, "ma"),
74+
"mb": String(0, 64, "mb"),
75+
},
76+
}
77+
s := schema.Schema{
78+
Description: "example request",
79+
Fields: schema.Fields{
80+
"a": RFC3339Nano(),
81+
"b": RFC3339Nano(),
82+
"c": String(0, 100, "b"),
83+
"d": Default(Integer(0, math.MaxInt64, "c"), 100),
84+
"e": Default(Integer(0, math.MaxInt64, "d"), 100),
85+
"f": Default(Integer(0, 100, "e"), 100),
86+
"g": Default(Integer(0, math.MaxInt64, "f"), 100),
87+
"h": Required(String(0, 65535, "h")),
88+
"i": Required(String(0, 65535, "i")),
89+
"j": Required(String(0, 255, "j")),
90+
"k": Required(String(0, 255, "k")),
91+
"l": Required(String(0, 65535, "l")),
92+
"m": schema.Field{
93+
Description: "m",
94+
Validator: &schema.Array{
95+
ValuesValidator: &schema.Object{
96+
Schema: mSchema,
97+
},
98+
},
99+
},
100+
},
101+
}
102+
s.Compile()
103+
return s
104+
}
105+
106+
func getComplexSchema2() schema.Schema {
107+
108+
cSchema := &schema.Schema{
109+
Description: "c schema",
110+
Fields: schema.Fields{
111+
"ca": RFC3339Nano(),
112+
"cb": String(0, 64, "cb"),
113+
"cc": Integer(0, 65535, "cc"),
114+
"cd": Integer(0, 65535, "cd"),
115+
"ce": Integer(0, math.MaxInt64, "ce"),
116+
"cf": Required(String(0, 128, "cf")),
117+
"cg": Required(String(0, 128, "cg")),
118+
"ch": Integer(0, math.MaxInt64, "ch"),
119+
"ci": Integer(0, math.MaxInt64, "ci"),
120+
"cj": Integer(0, math.MaxInt64, "cj"),
121+
"ck": Integer(0, math.MaxInt64, "ck"),
122+
},
123+
}
124+
gSchema := &schema.Schema{
125+
Description: "gSchema",
126+
Fields: schema.Fields{
127+
"ga": Required(String(0, 64, "ga")),
128+
"gb": Required(String(0, 64, "gb")),
129+
"gc": Required(String(0, 64, "gc")),
130+
"gd": Required(String(0, 64, "gd")),
131+
"ge": Required(String(0, 64, "ge")),
132+
},
133+
}
134+
iSchema := &schema.Schema{
135+
Description: "iSchema",
136+
Fields: schema.Fields{
137+
"ia": Integer(0, math.MaxInt64, "ia"),
138+
"ib": Integer(0, math.MaxInt64, "ib"),
139+
"ic": Integer(0, math.MaxInt64, "ic"),
140+
"id": RFC3339Nano(),
141+
},
142+
}
143+
dSchema := &schema.Schema{
144+
Description: "dSchema",
145+
Fields: schema.Fields{
146+
"da": Required(String(0, 128, "da")),
147+
"db": Required(String(0, 32, "db")),
148+
"dc": RFC3339Nano(),
149+
"dd": RFC3339Nano(),
150+
"de": Integer(0, 99999, "de"),
151+
"df": Integer(0, 100, "df"),
152+
"dg": schema.Field{
153+
Description: "dg",
154+
Validator: &schema.Object{
155+
Schema: gSchema,
156+
},
157+
},
158+
"dh": Required(Bool("dh")),
159+
"di": schema.Field{
160+
Description: "di",
161+
Validator: &schema.Object{
162+
Schema: iSchema,
163+
},
164+
},
165+
},
166+
}
167+
s := schema.Schema{
168+
Description: "example response",
169+
Fields: schema.Fields{
170+
"a": Required(String(16, 16, "a")),
171+
"b": Required(String(0, 56, "b")),
172+
"c": schema.Field{
173+
Description: "c",
174+
Required: true,
175+
Validator: &schema.Array{
176+
ValuesValidator: &schema.Object{
177+
Schema: cSchema,
178+
},
179+
},
180+
},
181+
"d": schema.Field{
182+
Description: "d",
183+
Required: true,
184+
Validator: &schema.Array{
185+
ValuesValidator: &schema.Object{
186+
Schema: dSchema,
187+
},
188+
},
189+
},
190+
"e": Required(String(0, 65335, "e")),
191+
"f": schema.Field{
192+
Validator: &schema.String{},
193+
Description: "f",
194+
},
195+
"g": schema.Field{
196+
Validator: &schema.String{},
197+
Description: "g",
198+
},
199+
},
200+
}
201+
s.Compile()
202+
return s
203+
}

schema/encoding/jsonschema/benchmark_test.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,25 @@ func BenchmarkEncoder(b *testing.B) {
3838
},
3939
},
4040
{
41-
Name: `Schema=Student`,
41+
Name: `Schema=Simple`,
4242
Schema: studentSchema,
4343
},
44+
{
45+
Name: `Schema=Complex1`,
46+
Schema: getComplexSchema1(),
47+
},
48+
{
49+
Name: `Schema=Complex2`,
50+
Schema: getComplexSchema2(),
51+
},
4452
}
4553
for i := range testCases {
54+
buf := bytes.NewBuffer(make([]byte, 2<<19))
4655
tc := testCases[i]
4756
b.Run(tc.Name, func(b *testing.B) {
4857
for i := 0; i < b.N; i++ {
49-
enc := jsonschema.NewEncoder(new(bytes.Buffer))
58+
buf.Truncate(0)
59+
enc := jsonschema.NewEncoder(buf)
5060
enc.Encode(&tc.Schema)
5161
}
5262
})

0 commit comments

Comments
 (0)