Skip to content

Commit c354f40

Browse files
yanfalirs
authored andcommitted
Add a more complex schema benchmark (#78)
- 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 not interested in measuring that. - Set Buffer to 512Kb to avoid dynamic schema growth for expected test usage.
1 parent 358e806 commit c354f40

File tree

2 files changed

+214
-2
lines changed

2 files changed

+214
-2
lines changed
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
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+
cSchema := &schema.Schema{
108+
Description: "c schema",
109+
Fields: schema.Fields{
110+
"ca": RFC3339Nano(),
111+
"cb": String(0, 64, "cb"),
112+
"cc": Integer(0, 65535, "cc"),
113+
"cd": Integer(0, 65535, "cd"),
114+
"ce": Integer(0, math.MaxInt64, "ce"),
115+
"cf": Required(String(0, 128, "cf")),
116+
"cg": Required(String(0, 128, "cg")),
117+
"ch": Integer(0, math.MaxInt64, "ch"),
118+
"ci": Integer(0, math.MaxInt64, "ci"),
119+
"cj": Integer(0, math.MaxInt64, "cj"),
120+
"ck": Integer(0, math.MaxInt64, "ck"),
121+
},
122+
}
123+
gSchema := &schema.Schema{
124+
Description: "gSchema",
125+
Fields: schema.Fields{
126+
"ga": Required(String(0, 64, "ga")),
127+
"gb": Required(String(0, 64, "gb")),
128+
"gc": Required(String(0, 64, "gc")),
129+
"gd": Required(String(0, 64, "gd")),
130+
"ge": Required(String(0, 64, "ge")),
131+
},
132+
}
133+
iSchema := &schema.Schema{
134+
Description: "iSchema",
135+
Fields: schema.Fields{
136+
"ia": Integer(0, math.MaxInt64, "ia"),
137+
"ib": Integer(0, math.MaxInt64, "ib"),
138+
"ic": Integer(0, math.MaxInt64, "ic"),
139+
"id": RFC3339Nano(),
140+
},
141+
}
142+
dSchema := &schema.Schema{
143+
Description: "dSchema",
144+
Fields: schema.Fields{
145+
"da": Required(String(0, 128, "da")),
146+
"db": Required(String(0, 32, "db")),
147+
"dc": RFC3339Nano(),
148+
"dd": RFC3339Nano(),
149+
"de": Integer(0, 99999, "de"),
150+
"df": Integer(0, 100, "df"),
151+
"dg": schema.Field{
152+
Description: "dg",
153+
Validator: &schema.Object{
154+
Schema: gSchema,
155+
},
156+
},
157+
"dh": Required(Bool("dh")),
158+
"di": schema.Field{
159+
Description: "di",
160+
Validator: &schema.Object{
161+
Schema: iSchema,
162+
},
163+
},
164+
},
165+
}
166+
s := schema.Schema{
167+
Description: "example response",
168+
Fields: schema.Fields{
169+
"a": Required(String(16, 16, "a")),
170+
"b": Required(String(0, 56, "b")),
171+
"c": schema.Field{
172+
Description: "c",
173+
Required: true,
174+
Validator: &schema.Array{
175+
ValuesValidator: &schema.Object{
176+
Schema: cSchema,
177+
},
178+
},
179+
},
180+
"d": schema.Field{
181+
Description: "d",
182+
Required: true,
183+
Validator: &schema.Array{
184+
ValuesValidator: &schema.Object{
185+
Schema: dSchema,
186+
},
187+
},
188+
},
189+
"e": Required(String(0, 65335, "e")),
190+
"f": schema.Field{
191+
Validator: &schema.String{},
192+
Description: "f",
193+
},
194+
"g": schema.Field{
195+
Validator: &schema.String{},
196+
Description: "g",
197+
},
198+
},
199+
}
200+
s.Compile()
201+
return s
202+
}

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)