Skip to content

Commit 492703a

Browse files
joeybloggsjoeybloggs
authored andcommitted
Add struct benchmark + fix recursive struct bug
1 parent 024a390 commit 492703a

File tree

3 files changed

+444
-13
lines changed

3 files changed

+444
-13
lines changed

benchmarks/benchmarks_test.go

Lines changed: 370 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,370 @@
1+
package benchmarks
2+
3+
import (
4+
"net/url"
5+
"testing"
6+
7+
"github.com/go-playground/form"
8+
)
9+
10+
// Simple Benchmarks
11+
12+
type User struct {
13+
FirstName string `form:"fname"`
14+
LastName string `form:"lname"`
15+
Email string `form:"email"`
16+
Age uint8 `form:"age"`
17+
}
18+
19+
func getUserStructValues() url.Values {
20+
return url.Values{
21+
"fname": []string{"Joey"},
22+
"lname": []string{"Bloggs"},
23+
"email": []string{"[email protected]"},
24+
"age": []string{"32"},
25+
}
26+
}
27+
28+
func BenchmarkSimpleUserStruct(b *testing.B) {
29+
30+
values := getUserStructValues()
31+
decoder := form.NewDecoder()
32+
var err error
33+
b.ReportAllocs()
34+
for n := 0; n < b.N; n++ {
35+
var test User
36+
if err = decoder.Decode(&test, values); err != nil {
37+
b.Error(err)
38+
}
39+
}
40+
}
41+
42+
func BenchmarkSimpleUserStructParallel(b *testing.B) {
43+
44+
values := getUserStructValues()
45+
decoder := form.NewDecoder()
46+
var err error
47+
48+
b.ReportAllocs()
49+
b.RunParallel(func(pb *testing.PB) {
50+
for pb.Next() {
51+
var test User
52+
if err = decoder.Decode(&test, values); err != nil {
53+
b.Error(err)
54+
}
55+
}
56+
})
57+
}
58+
59+
// Primitives ALL types
60+
61+
type PrimitivesStruct struct {
62+
String string
63+
Int int
64+
Int8 int8
65+
Int16 int16
66+
Int32 int32
67+
Int64 int64
68+
Uint uint
69+
Uint8 uint8
70+
Uint16 uint16
71+
Uint32 uint32
72+
Uint64 uint64
73+
Float32 float32
74+
Float64 float64
75+
Bool bool
76+
}
77+
78+
func getPrimitivesStructValues() url.Values {
79+
return url.Values{
80+
"String": []string{"joeybloggs"},
81+
"Int": []string{"1"},
82+
"Int8": []string{"2"},
83+
"Int16": []string{"3"},
84+
"Int32": []string{"4"},
85+
"Int64": []string{"5"},
86+
"Uint": []string{"1"},
87+
"Uint8": []string{"2"},
88+
"Uint16": []string{"3"},
89+
"Uint32": []string{"4"},
90+
"Uint64": []string{"5"},
91+
"Float32": []string{"1.1"},
92+
"Float64": []string{"5.0"},
93+
"Bool": []string{"t"},
94+
}
95+
}
96+
97+
func BenchmarkPrimitivesStructAllPrimitivesTypes(b *testing.B) {
98+
values := getPrimitivesStructValues()
99+
decoder := form.NewDecoder()
100+
var err error
101+
102+
b.ReportAllocs()
103+
for n := 0; n < b.N; n++ {
104+
var test PrimitivesStruct
105+
if err = decoder.Decode(&test, values); err != nil {
106+
b.Error(err)
107+
}
108+
}
109+
}
110+
111+
func BenchmarkPrimitivesStructAllPrimitivesTypesParallel(b *testing.B) {
112+
values := getPrimitivesStructValues()
113+
decoder := form.NewDecoder()
114+
var err error
115+
116+
b.ReportAllocs()
117+
b.RunParallel(func(pb *testing.PB) {
118+
for pb.Next() {
119+
var test PrimitivesStruct
120+
if err = decoder.Decode(&test, values); err != nil {
121+
b.Error(err)
122+
}
123+
}
124+
})
125+
}
126+
127+
// Complex Array ALL types
128+
129+
type ComplexArrayStruct struct {
130+
String []string
131+
StringPtr []*string
132+
Int []int
133+
IntPtr []*int
134+
Int8 []int8
135+
Int8Ptr []*int8
136+
Int16 []int16
137+
Int16Ptr []*int16
138+
Int32 []int32
139+
Int32Ptr []*int32
140+
Int64 []int64
141+
Int64Ptr []*int64
142+
Uint []uint
143+
UintPtr []*uint
144+
Uint8 []uint8
145+
Uint8Ptr []*uint8
146+
Uint16 []uint16
147+
UInt16Ptr []*uint16
148+
UInt32 []uint32
149+
Uint31Ptr []*uint32
150+
Uint64 []uint64
151+
Uint64Ptr []*uint64
152+
NestedInt [][]int
153+
NestedIntPtr [][]*int
154+
}
155+
156+
func getComplexArrayStructValues() url.Values {
157+
return url.Values{
158+
"String": []string{"joeybloggs"},
159+
"StringPtr": []string{"joeybloggs"},
160+
"Int": []string{"1", "2"},
161+
"IntPtr": []string{"1", "2"},
162+
"Int8[0]": []string{"1"},
163+
"Int8[1]": []string{"2"},
164+
"Int8Ptr[0]": []string{"1"},
165+
"Int8Ptr[1]": []string{"2"},
166+
"Int16": []string{"1", "2"},
167+
"Int16Ptr": []string{"1", "2"},
168+
"Int32": []string{"1", "2"},
169+
"Int32Ptr": []string{"1", "2"},
170+
"Int64": []string{"1", "2"},
171+
"Int64Ptr": []string{"1", "2"},
172+
"Uint": []string{"1", "2"},
173+
"UintPtr": []string{"1", "2"},
174+
"Uint8[0]": []string{"1"},
175+
"Uint8[1]": []string{"2"},
176+
"Uint8Ptr[0]": []string{"1"},
177+
"Uint8Ptr[1]": []string{"2"},
178+
"Uint16": []string{"1", "2"},
179+
"Uint16Ptr": []string{"1", "2"},
180+
"Uint32": []string{"1", "2"},
181+
"Uint32Ptr": []string{"1", "2"},
182+
"Uint64": []string{"1", "2"},
183+
"Uint64Ptr": []string{"1", "2"},
184+
"NestedInt[0][0]": []string{"1"},
185+
"NestedIntPtr[0][1]": []string{"1"},
186+
}
187+
}
188+
189+
func BenchmarkComplexArrayStructAllTypes(b *testing.B) {
190+
values := getComplexArrayStructValues()
191+
decoder := form.NewDecoder()
192+
var err error
193+
194+
b.ReportAllocs()
195+
for n := 0; n < b.N; n++ {
196+
var test ComplexArrayStruct
197+
if err = decoder.Decode(&test, values); err != nil {
198+
b.Error(err)
199+
}
200+
}
201+
}
202+
203+
func BenchmarkComplexArrayStructAllTypesParallel(b *testing.B) {
204+
values := getComplexArrayStructValues()
205+
decoder := form.NewDecoder()
206+
var err error
207+
208+
b.ReportAllocs()
209+
b.RunParallel(func(pb *testing.PB) {
210+
for pb.Next() {
211+
var test ComplexArrayStruct
212+
if err = decoder.Decode(&test, values); err != nil {
213+
b.Error(err)
214+
}
215+
}
216+
})
217+
}
218+
219+
// Complex Map ALL types
220+
221+
type ComplexMapStruct struct {
222+
String map[string]string
223+
StringPtr map[*string]*string
224+
Int map[int]int
225+
IntPtr map[*int]*int
226+
Int8 map[int8]int8
227+
Int8Ptr map[*int8]*int8
228+
Int16 map[int16]int16
229+
Int16Ptr map[*int16]*int16
230+
Int32 map[int32]int32
231+
Int32Ptr map[*int32]*int32
232+
Int64 map[int64]int64
233+
Int64Ptr map[*int64]*int64
234+
Uint map[uint]uint
235+
UintPtr map[*uint]*uint
236+
Uint8 map[uint8]uint8
237+
Uint8Ptr map[*uint8]*uint8
238+
Uint16 map[uint16]uint16
239+
UInt16Ptr map[*uint16]*uint16
240+
UInt32 map[*uint32]*uint32
241+
Uint31Ptr map[*uint32]*uint32
242+
Uint64 map[*uint64]*uint64
243+
Uint64Ptr map[*uint64]*uint64
244+
NestedInt map[int]map[int]int
245+
NestedIntPtr map[*int]map[*int]*int
246+
}
247+
248+
func getComplexMapStructValues() url.Values {
249+
return url.Values{
250+
"String[key]": []string{"value"},
251+
"StringPtr[key]": []string{"value"},
252+
"Int[0]": []string{"1"},
253+
"IntPtr[0]": []string{"1"},
254+
"Int8[0]": []string{"1"},
255+
"Int8Ptr[0]": []string{"1"},
256+
"Int16[0]": []string{"1"},
257+
"Int16Ptr[0]": []string{"1"},
258+
"Int32[0]": []string{"1"},
259+
"Int32Ptr[0]": []string{"1"},
260+
"Int64[0]": []string{"1"},
261+
"Int64Ptr[0]": []string{"1"},
262+
"Uint[0]": []string{"1"},
263+
"UintPtr[0]": []string{"1"},
264+
"Uint8[0]": []string{"1"},
265+
"Uint8Ptr[0]": []string{"1"},
266+
"Uint16[0]": []string{"1"},
267+
"Uint16Ptr[0]": []string{"1"},
268+
"Uint32[0]": []string{"1"},
269+
"Uint32Ptr[0]": []string{"1"},
270+
"Uint64[0]": []string{"1"},
271+
"Uint64Ptr[0]": []string{"1"},
272+
"NestedInt[1][2]": []string{"3"},
273+
"NestedIntPtr[1][2]": []string{"3"},
274+
}
275+
}
276+
277+
func BenchmarkComplexMapStructAllTypes(b *testing.B) {
278+
values := getComplexMapStructValues()
279+
decoder := form.NewDecoder()
280+
var err error
281+
282+
b.ReportAllocs()
283+
for n := 0; n < b.N; n++ {
284+
var test ComplexMapStruct
285+
if err = decoder.Decode(&test, values); err != nil {
286+
b.Error(err)
287+
}
288+
}
289+
}
290+
291+
func BenchmarkComplexMapStructAllTypesParallel(b *testing.B) {
292+
values := getComplexMapStructValues()
293+
decoder := form.NewDecoder()
294+
var err error
295+
296+
b.ReportAllocs()
297+
b.RunParallel(func(pb *testing.PB) {
298+
for pb.Next() {
299+
var test ComplexMapStruct
300+
if err = decoder.Decode(&test, values); err != nil {
301+
b.Error(err)
302+
}
303+
}
304+
})
305+
}
306+
307+
// NestedStruct Benchmarks
308+
309+
type Nested2 struct {
310+
Value string
311+
Nested2 *Nested2
312+
}
313+
314+
type Nested struct {
315+
Value string
316+
}
317+
318+
type NestedStruct struct {
319+
Nested
320+
NestedArray []Nested
321+
NestedPtrArray []*Nested
322+
Nested2 Nested2
323+
}
324+
325+
func getNestedStructValues() url.Values {
326+
return url.Values{
327+
// Nested Field
328+
"Value": []string{"value"},
329+
// Nested Array
330+
"NestedArray[0].Value": []string{"value"},
331+
"NestedArray[1].Value": []string{"value"},
332+
// Nested Array Ptr
333+
"NestedArrayPtr[0].Value": []string{"value"},
334+
"NestedArrayPtr[1].Value": []string{"value"},
335+
// Nested 2
336+
"Nested2.Value": []string{"value"},
337+
"Nested2.Nested2.Value": []string{"value"},
338+
}
339+
}
340+
341+
func BenchmarkArrayMapNestedStruct(b *testing.B) {
342+
343+
values := getNestedStructValues()
344+
decoder := form.NewDecoder()
345+
var err error
346+
b.ReportAllocs()
347+
for n := 0; n < b.N; n++ {
348+
var test NestedStruct
349+
if err = decoder.Decode(&test, values); err != nil {
350+
b.Error(err)
351+
}
352+
}
353+
}
354+
355+
func BenchmarkArrayMapNestedStructParallel(b *testing.B) {
356+
357+
values := getNestedStructValues()
358+
decoder := form.NewDecoder()
359+
var err error
360+
361+
b.ReportAllocs()
362+
b.RunParallel(func(pb *testing.PB) {
363+
for pb.Next() {
364+
var test NestedStruct
365+
if err = decoder.Decode(&test, values); err != nil {
366+
b.Error(err)
367+
}
368+
}
369+
})
370+
}

0 commit comments

Comments
 (0)