benchmarks_test.go 20 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. package validator
  2. import (
  3. "bytes"
  4. sql "database/sql/driver"
  5. "testing"
  6. "time"
  7. )
  8. func BenchmarkFieldSuccess(b *testing.B) {
  9. validate := New()
  10. s := "1"
  11. b.ResetTimer()
  12. for n := 0; n < b.N; n++ {
  13. _ = validate.Var(&s, "len=1")
  14. }
  15. }
  16. func BenchmarkFieldSuccessParallel(b *testing.B) {
  17. validate := New()
  18. s := "1"
  19. b.ResetTimer()
  20. b.RunParallel(func(pb *testing.PB) {
  21. for pb.Next() {
  22. _ = validate.Var(&s, "len=1")
  23. }
  24. })
  25. }
  26. func BenchmarkFieldFailure(b *testing.B) {
  27. validate := New()
  28. s := "12"
  29. b.ResetTimer()
  30. for n := 0; n < b.N; n++ {
  31. _ = validate.Var(&s, "len=1")
  32. }
  33. }
  34. func BenchmarkFieldFailureParallel(b *testing.B) {
  35. validate := New()
  36. s := "12"
  37. b.ResetTimer()
  38. b.RunParallel(func(pb *testing.PB) {
  39. for pb.Next() {
  40. _ = validate.Var(&s, "len=1")
  41. }
  42. })
  43. }
  44. func BenchmarkFieldArrayDiveSuccess(b *testing.B) {
  45. validate := New()
  46. m := []string{"val1", "val2", "val3"}
  47. b.ResetTimer()
  48. for n := 0; n < b.N; n++ {
  49. _ = validate.Var(m, "required,dive,required")
  50. }
  51. }
  52. func BenchmarkFieldArrayDiveSuccessParallel(b *testing.B) {
  53. validate := New()
  54. m := []string{"val1", "val2", "val3"}
  55. b.ResetTimer()
  56. b.RunParallel(func(pb *testing.PB) {
  57. for pb.Next() {
  58. _ = validate.Var(m, "required,dive,required")
  59. }
  60. })
  61. }
  62. func BenchmarkFieldArrayDiveFailure(b *testing.B) {
  63. validate := New()
  64. m := []string{"val1", "", "val3"}
  65. b.ResetTimer()
  66. for n := 0; n < b.N; n++ {
  67. _ = validate.Var(m, "required,dive,required")
  68. }
  69. }
  70. func BenchmarkFieldArrayDiveFailureParallel(b *testing.B) {
  71. validate := New()
  72. m := []string{"val1", "", "val3"}
  73. b.ResetTimer()
  74. b.RunParallel(func(pb *testing.PB) {
  75. for pb.Next() {
  76. _ = validate.Var(m, "required,dive,required")
  77. }
  78. })
  79. }
  80. func BenchmarkFieldMapDiveSuccess(b *testing.B) {
  81. validate := New()
  82. m := map[string]string{"val1": "val1", "val2": "val2", "val3": "val3"}
  83. b.ResetTimer()
  84. for n := 0; n < b.N; n++ {
  85. _ = validate.Var(m, "required,dive,required")
  86. }
  87. }
  88. func BenchmarkFieldMapDiveSuccessParallel(b *testing.B) {
  89. validate := New()
  90. m := map[string]string{"val1": "val1", "val2": "val2", "val3": "val3"}
  91. b.ResetTimer()
  92. b.RunParallel(func(pb *testing.PB) {
  93. for pb.Next() {
  94. _ = validate.Var(m, "required,dive,required")
  95. }
  96. })
  97. }
  98. func BenchmarkFieldMapDiveFailure(b *testing.B) {
  99. validate := New()
  100. m := map[string]string{"": "", "val3": "val3"}
  101. b.ResetTimer()
  102. for n := 0; n < b.N; n++ {
  103. _ = validate.Var(m, "required,dive,required")
  104. }
  105. }
  106. func BenchmarkFieldMapDiveFailureParallel(b *testing.B) {
  107. validate := New()
  108. m := map[string]string{"": "", "val3": "val3"}
  109. b.ResetTimer()
  110. b.RunParallel(func(pb *testing.PB) {
  111. for pb.Next() {
  112. _ = validate.Var(m, "required,dive,required")
  113. }
  114. })
  115. }
  116. func BenchmarkFieldMapDiveWithKeysSuccess(b *testing.B) {
  117. validate := New()
  118. m := map[string]string{"val1": "val1", "val2": "val2", "val3": "val3"}
  119. b.ResetTimer()
  120. for n := 0; n < b.N; n++ {
  121. _ = validate.Var(m, "required,dive,keys,required,endkeys,required")
  122. }
  123. }
  124. func BenchmarkFieldMapDiveWithKeysSuccessParallel(b *testing.B) {
  125. validate := New()
  126. m := map[string]string{"val1": "val1", "val2": "val2", "val3": "val3"}
  127. b.ResetTimer()
  128. b.RunParallel(func(pb *testing.PB) {
  129. for pb.Next() {
  130. _ = validate.Var(m, "required,dive,keys,required,endkeys,required")
  131. }
  132. })
  133. }
  134. func BenchmarkFieldMapDiveWithKeysFailure(b *testing.B) {
  135. validate := New()
  136. m := map[string]string{"": "", "val3": "val3"}
  137. b.ResetTimer()
  138. for n := 0; n < b.N; n++ {
  139. _ = validate.Var(m, "required,dive,keys,required,endkeys,required")
  140. }
  141. }
  142. func BenchmarkFieldMapDiveWithKeysFailureParallel(b *testing.B) {
  143. validate := New()
  144. m := map[string]string{"": "", "val3": "val3"}
  145. b.ResetTimer()
  146. b.RunParallel(func(pb *testing.PB) {
  147. for pb.Next() {
  148. _ = validate.Var(m, "required,dive,keys,required,endkeys,required")
  149. }
  150. })
  151. }
  152. func BenchmarkFieldCustomTypeSuccess(b *testing.B) {
  153. validate := New()
  154. validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
  155. val := valuer{
  156. Name: "1",
  157. }
  158. b.ResetTimer()
  159. for n := 0; n < b.N; n++ {
  160. _ = validate.Var(val, "len=1")
  161. }
  162. }
  163. func BenchmarkFieldCustomTypeSuccessParallel(b *testing.B) {
  164. validate := New()
  165. validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
  166. val := valuer{
  167. Name: "1",
  168. }
  169. b.ResetTimer()
  170. b.RunParallel(func(pb *testing.PB) {
  171. for pb.Next() {
  172. _ = validate.Var(val, "len=1")
  173. }
  174. })
  175. }
  176. func BenchmarkFieldCustomTypeFailure(b *testing.B) {
  177. validate := New()
  178. validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
  179. val := valuer{}
  180. b.ResetTimer()
  181. for n := 0; n < b.N; n++ {
  182. _ = validate.Var(val, "len=1")
  183. }
  184. }
  185. func BenchmarkFieldCustomTypeFailureParallel(b *testing.B) {
  186. validate := New()
  187. validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
  188. val := valuer{}
  189. b.ResetTimer()
  190. b.RunParallel(func(pb *testing.PB) {
  191. for pb.Next() {
  192. _ = validate.Var(val, "len=1")
  193. }
  194. })
  195. }
  196. func BenchmarkFieldOrTagSuccess(b *testing.B) {
  197. validate := New()
  198. s := "rgba(0,0,0,1)"
  199. b.ResetTimer()
  200. for n := 0; n < b.N; n++ {
  201. _ = validate.Var(s, "rgb|rgba")
  202. }
  203. }
  204. func BenchmarkFieldOrTagSuccessParallel(b *testing.B) {
  205. validate := New()
  206. s := "rgba(0,0,0,1)"
  207. b.ResetTimer()
  208. b.RunParallel(func(pb *testing.PB) {
  209. for pb.Next() {
  210. _ = validate.Var(s, "rgb|rgba")
  211. }
  212. })
  213. }
  214. func BenchmarkFieldOrTagFailure(b *testing.B) {
  215. validate := New()
  216. s := "#000"
  217. b.ResetTimer()
  218. for n := 0; n < b.N; n++ {
  219. _ = validate.Var(s, "rgb|rgba")
  220. }
  221. }
  222. func BenchmarkFieldOrTagFailureParallel(b *testing.B) {
  223. validate := New()
  224. s := "#000"
  225. b.ResetTimer()
  226. b.RunParallel(func(pb *testing.PB) {
  227. for pb.Next() {
  228. _ = validate.Var(s, "rgb|rgba")
  229. }
  230. })
  231. }
  232. func BenchmarkStructLevelValidationSuccess(b *testing.B) {
  233. validate := New()
  234. validate.RegisterStructValidation(StructValidationTestStructSuccess, TestStruct{})
  235. tst := TestStruct{
  236. String: "good value",
  237. }
  238. b.ResetTimer()
  239. for n := 0; n < b.N; n++ {
  240. _ = validate.Struct(tst)
  241. }
  242. }
  243. func BenchmarkStructLevelValidationSuccessParallel(b *testing.B) {
  244. validate := New()
  245. validate.RegisterStructValidation(StructValidationTestStructSuccess, TestStruct{})
  246. tst := TestStruct{
  247. String: "good value",
  248. }
  249. b.ResetTimer()
  250. b.RunParallel(func(pb *testing.PB) {
  251. for pb.Next() {
  252. _ = validate.Struct(tst)
  253. }
  254. })
  255. }
  256. func BenchmarkStructLevelValidationFailure(b *testing.B) {
  257. validate := New()
  258. validate.RegisterStructValidation(StructValidationTestStruct, TestStruct{})
  259. tst := TestStruct{
  260. String: "good value",
  261. }
  262. b.ResetTimer()
  263. for n := 0; n < b.N; n++ {
  264. _ = validate.Struct(tst)
  265. }
  266. }
  267. func BenchmarkStructLevelValidationFailureParallel(b *testing.B) {
  268. validate := New()
  269. validate.RegisterStructValidation(StructValidationTestStruct, TestStruct{})
  270. tst := TestStruct{
  271. String: "good value",
  272. }
  273. b.ResetTimer()
  274. b.RunParallel(func(pb *testing.PB) {
  275. for pb.Next() {
  276. _ = validate.Struct(tst)
  277. }
  278. })
  279. }
  280. func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) {
  281. validate := New()
  282. validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
  283. val := valuer{
  284. Name: "1",
  285. }
  286. type Foo struct {
  287. Valuer valuer `validate:"len=1"`
  288. IntValue int `validate:"min=5,max=10"`
  289. }
  290. validFoo := &Foo{Valuer: val, IntValue: 7}
  291. b.ResetTimer()
  292. for n := 0; n < b.N; n++ {
  293. _ = validate.Struct(validFoo)
  294. }
  295. }
  296. func BenchmarkStructSimpleCustomTypeSuccessParallel(b *testing.B) {
  297. validate := New()
  298. validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
  299. val := valuer{
  300. Name: "1",
  301. }
  302. type Foo struct {
  303. Valuer valuer `validate:"len=1"`
  304. IntValue int `validate:"min=5,max=10"`
  305. }
  306. validFoo := &Foo{Valuer: val, IntValue: 7}
  307. b.ResetTimer()
  308. b.RunParallel(func(pb *testing.PB) {
  309. for pb.Next() {
  310. _ = validate.Struct(validFoo)
  311. }
  312. })
  313. }
  314. func BenchmarkStructSimpleCustomTypeFailure(b *testing.B) {
  315. validate := New()
  316. validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
  317. val := valuer{}
  318. type Foo struct {
  319. Valuer valuer `validate:"len=1"`
  320. IntValue int `validate:"min=5,max=10"`
  321. }
  322. validFoo := &Foo{Valuer: val, IntValue: 3}
  323. b.ResetTimer()
  324. for n := 0; n < b.N; n++ {
  325. _ = validate.Struct(validFoo)
  326. }
  327. }
  328. func BenchmarkStructSimpleCustomTypeFailureParallel(b *testing.B) {
  329. validate := New()
  330. validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
  331. val := valuer{}
  332. type Foo struct {
  333. Valuer valuer `validate:"len=1"`
  334. IntValue int `validate:"min=5,max=10"`
  335. }
  336. validFoo := &Foo{Valuer: val, IntValue: 3}
  337. b.ResetTimer()
  338. b.RunParallel(func(pb *testing.PB) {
  339. for pb.Next() {
  340. _ = validate.Struct(validate.Struct(validFoo))
  341. }
  342. })
  343. }
  344. func BenchmarkStructFilteredSuccess(b *testing.B) {
  345. validate := New()
  346. type Test struct {
  347. Name string `validate:"required"`
  348. NickName string `validate:"required"`
  349. }
  350. test := &Test{
  351. Name: "Joey Bloggs",
  352. }
  353. byts := []byte("Name")
  354. fn := func(ns []byte) bool {
  355. return !bytes.HasSuffix(ns, byts)
  356. }
  357. b.ResetTimer()
  358. for n := 0; n < b.N; n++ {
  359. _ = validate.StructFiltered(test, fn)
  360. }
  361. }
  362. func BenchmarkStructFilteredSuccessParallel(b *testing.B) {
  363. validate := New()
  364. type Test struct {
  365. Name string `validate:"required"`
  366. NickName string `validate:"required"`
  367. }
  368. test := &Test{
  369. Name: "Joey Bloggs",
  370. }
  371. byts := []byte("Name")
  372. fn := func(ns []byte) bool {
  373. return !bytes.HasSuffix(ns, byts)
  374. }
  375. b.ResetTimer()
  376. b.RunParallel(func(pb *testing.PB) {
  377. for pb.Next() {
  378. _ = validate.StructFiltered(test, fn)
  379. }
  380. })
  381. }
  382. func BenchmarkStructFilteredFailure(b *testing.B) {
  383. validate := New()
  384. type Test struct {
  385. Name string `validate:"required"`
  386. NickName string `validate:"required"`
  387. }
  388. test := &Test{
  389. Name: "Joey Bloggs",
  390. }
  391. byts := []byte("NickName")
  392. fn := func(ns []byte) bool {
  393. return !bytes.HasSuffix(ns, byts)
  394. }
  395. b.ResetTimer()
  396. for n := 0; n < b.N; n++ {
  397. _ = validate.StructFiltered(test, fn)
  398. }
  399. }
  400. func BenchmarkStructFilteredFailureParallel(b *testing.B) {
  401. validate := New()
  402. type Test struct {
  403. Name string `validate:"required"`
  404. NickName string `validate:"required"`
  405. }
  406. test := &Test{
  407. Name: "Joey Bloggs",
  408. }
  409. byts := []byte("NickName")
  410. fn := func(ns []byte) bool {
  411. return !bytes.HasSuffix(ns, byts)
  412. }
  413. b.ResetTimer()
  414. b.RunParallel(func(pb *testing.PB) {
  415. for pb.Next() {
  416. _ = validate.StructFiltered(test, fn)
  417. }
  418. })
  419. }
  420. func BenchmarkStructPartialSuccess(b *testing.B) {
  421. validate := New()
  422. type Test struct {
  423. Name string `validate:"required"`
  424. NickName string `validate:"required"`
  425. }
  426. test := &Test{
  427. Name: "Joey Bloggs",
  428. }
  429. b.ResetTimer()
  430. for n := 0; n < b.N; n++ {
  431. _ = validate.StructPartial(test, "Name")
  432. }
  433. }
  434. func BenchmarkStructPartialSuccessParallel(b *testing.B) {
  435. validate := New()
  436. type Test struct {
  437. Name string `validate:"required"`
  438. NickName string `validate:"required"`
  439. }
  440. test := &Test{
  441. Name: "Joey Bloggs",
  442. }
  443. b.ResetTimer()
  444. b.RunParallel(func(pb *testing.PB) {
  445. for pb.Next() {
  446. _ = validate.StructPartial(test, "Name")
  447. }
  448. })
  449. }
  450. func BenchmarkStructPartialFailure(b *testing.B) {
  451. validate := New()
  452. type Test struct {
  453. Name string `validate:"required"`
  454. NickName string `validate:"required"`
  455. }
  456. test := &Test{
  457. Name: "Joey Bloggs",
  458. }
  459. b.ResetTimer()
  460. for n := 0; n < b.N; n++ {
  461. _ = validate.StructPartial(test, "NickName")
  462. }
  463. }
  464. func BenchmarkStructPartialFailureParallel(b *testing.B) {
  465. validate := New()
  466. type Test struct {
  467. Name string `validate:"required"`
  468. NickName string `validate:"required"`
  469. }
  470. test := &Test{
  471. Name: "Joey Bloggs",
  472. }
  473. b.ResetTimer()
  474. b.RunParallel(func(pb *testing.PB) {
  475. for pb.Next() {
  476. _ = validate.StructPartial(test, "NickName")
  477. }
  478. })
  479. }
  480. func BenchmarkStructExceptSuccess(b *testing.B) {
  481. validate := New()
  482. type Test struct {
  483. Name string `validate:"required"`
  484. NickName string `validate:"required"`
  485. }
  486. test := &Test{
  487. Name: "Joey Bloggs",
  488. }
  489. b.ResetTimer()
  490. for n := 0; n < b.N; n++ {
  491. _ = validate.StructExcept(test, "Nickname")
  492. }
  493. }
  494. func BenchmarkStructExceptSuccessParallel(b *testing.B) {
  495. validate := New()
  496. type Test struct {
  497. Name string `validate:"required"`
  498. NickName string `validate:"required"`
  499. }
  500. test := &Test{
  501. Name: "Joey Bloggs",
  502. }
  503. b.ResetTimer()
  504. b.RunParallel(func(pb *testing.PB) {
  505. for pb.Next() {
  506. _ = validate.StructExcept(test, "NickName")
  507. }
  508. })
  509. }
  510. func BenchmarkStructExceptFailure(b *testing.B) {
  511. validate := New()
  512. type Test struct {
  513. Name string `validate:"required"`
  514. NickName string `validate:"required"`
  515. }
  516. test := &Test{
  517. Name: "Joey Bloggs",
  518. }
  519. b.ResetTimer()
  520. for n := 0; n < b.N; n++ {
  521. _ = validate.StructExcept(test, "Name")
  522. }
  523. }
  524. func BenchmarkStructExceptFailureParallel(b *testing.B) {
  525. validate := New()
  526. type Test struct {
  527. Name string `validate:"required"`
  528. NickName string `validate:"required"`
  529. }
  530. test := &Test{
  531. Name: "Joey Bloggs",
  532. }
  533. b.ResetTimer()
  534. b.RunParallel(func(pb *testing.PB) {
  535. for pb.Next() {
  536. _ = validate.StructExcept(test, "Name")
  537. }
  538. })
  539. }
  540. func BenchmarkStructSimpleCrossFieldSuccess(b *testing.B) {
  541. validate := New()
  542. type Test struct {
  543. Start time.Time
  544. End time.Time `validate:"gtfield=Start"`
  545. }
  546. now := time.Now().UTC()
  547. then := now.Add(time.Hour * 5)
  548. test := &Test{
  549. Start: now,
  550. End: then,
  551. }
  552. b.ResetTimer()
  553. for n := 0; n < b.N; n++ {
  554. _ = validate.Struct(test)
  555. }
  556. }
  557. func BenchmarkStructSimpleCrossFieldSuccessParallel(b *testing.B) {
  558. validate := New()
  559. type Test struct {
  560. Start time.Time
  561. End time.Time `validate:"gtfield=Start"`
  562. }
  563. now := time.Now().UTC()
  564. then := now.Add(time.Hour * 5)
  565. test := &Test{
  566. Start: now,
  567. End: then,
  568. }
  569. b.ResetTimer()
  570. b.RunParallel(func(pb *testing.PB) {
  571. for pb.Next() {
  572. _ = validate.Struct(test)
  573. }
  574. })
  575. }
  576. func BenchmarkStructSimpleCrossFieldFailure(b *testing.B) {
  577. validate := New()
  578. type Test struct {
  579. Start time.Time
  580. End time.Time `validate:"gtfield=Start"`
  581. }
  582. now := time.Now().UTC()
  583. then := now.Add(time.Hour * -5)
  584. test := &Test{
  585. Start: now,
  586. End: then,
  587. }
  588. b.ResetTimer()
  589. for n := 0; n < b.N; n++ {
  590. _ = validate.Struct(test)
  591. }
  592. }
  593. func BenchmarkStructSimpleCrossFieldFailureParallel(b *testing.B) {
  594. validate := New()
  595. type Test struct {
  596. Start time.Time
  597. End time.Time `validate:"gtfield=Start"`
  598. }
  599. now := time.Now().UTC()
  600. then := now.Add(time.Hour * -5)
  601. test := &Test{
  602. Start: now,
  603. End: then,
  604. }
  605. b.ResetTimer()
  606. b.RunParallel(func(pb *testing.PB) {
  607. for pb.Next() {
  608. _ = validate.Struct(test)
  609. }
  610. })
  611. }
  612. func BenchmarkStructSimpleCrossStructCrossFieldSuccess(b *testing.B) {
  613. validate := New()
  614. type Inner struct {
  615. Start time.Time
  616. }
  617. type Outer struct {
  618. Inner *Inner
  619. CreatedAt time.Time `validate:"eqcsfield=Inner.Start"`
  620. }
  621. now := time.Now().UTC()
  622. inner := &Inner{
  623. Start: now,
  624. }
  625. outer := &Outer{
  626. Inner: inner,
  627. CreatedAt: now,
  628. }
  629. b.ResetTimer()
  630. for n := 0; n < b.N; n++ {
  631. _ = validate.Struct(outer)
  632. }
  633. }
  634. func BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel(b *testing.B) {
  635. validate := New()
  636. type Inner struct {
  637. Start time.Time
  638. }
  639. type Outer struct {
  640. Inner *Inner
  641. CreatedAt time.Time `validate:"eqcsfield=Inner.Start"`
  642. }
  643. now := time.Now().UTC()
  644. inner := &Inner{
  645. Start: now,
  646. }
  647. outer := &Outer{
  648. Inner: inner,
  649. CreatedAt: now,
  650. }
  651. b.ResetTimer()
  652. b.RunParallel(func(pb *testing.PB) {
  653. for pb.Next() {
  654. _ = validate.Struct(outer)
  655. }
  656. })
  657. }
  658. func BenchmarkStructSimpleCrossStructCrossFieldFailure(b *testing.B) {
  659. validate := New()
  660. type Inner struct {
  661. Start time.Time
  662. }
  663. type Outer struct {
  664. Inner *Inner
  665. CreatedAt time.Time `validate:"eqcsfield=Inner.Start"`
  666. }
  667. now := time.Now().UTC()
  668. then := now.Add(time.Hour * 5)
  669. inner := &Inner{
  670. Start: then,
  671. }
  672. outer := &Outer{
  673. Inner: inner,
  674. CreatedAt: now,
  675. }
  676. b.ResetTimer()
  677. for n := 0; n < b.N; n++ {
  678. _ = validate.Struct(outer)
  679. }
  680. }
  681. func BenchmarkStructSimpleCrossStructCrossFieldFailureParallel(b *testing.B) {
  682. validate := New()
  683. type Inner struct {
  684. Start time.Time
  685. }
  686. type Outer struct {
  687. Inner *Inner
  688. CreatedAt time.Time `validate:"eqcsfield=Inner.Start"`
  689. }
  690. now := time.Now().UTC()
  691. then := now.Add(time.Hour * 5)
  692. inner := &Inner{
  693. Start: then,
  694. }
  695. outer := &Outer{
  696. Inner: inner,
  697. CreatedAt: now,
  698. }
  699. b.ResetTimer()
  700. b.RunParallel(func(pb *testing.PB) {
  701. for pb.Next() {
  702. _ = validate.Struct(outer)
  703. }
  704. })
  705. }
  706. func BenchmarkStructSimpleSuccess(b *testing.B) {
  707. validate := New()
  708. type Foo struct {
  709. StringValue string `validate:"min=5,max=10"`
  710. IntValue int `validate:"min=5,max=10"`
  711. }
  712. validFoo := &Foo{StringValue: "Foobar", IntValue: 7}
  713. b.ResetTimer()
  714. for n := 0; n < b.N; n++ {
  715. _ = validate.Struct(validFoo)
  716. }
  717. }
  718. func BenchmarkStructSimpleSuccessParallel(b *testing.B) {
  719. validate := New()
  720. type Foo struct {
  721. StringValue string `validate:"min=5,max=10"`
  722. IntValue int `validate:"min=5,max=10"`
  723. }
  724. validFoo := &Foo{StringValue: "Foobar", IntValue: 7}
  725. b.ResetTimer()
  726. b.RunParallel(func(pb *testing.PB) {
  727. for pb.Next() {
  728. _ = validate.Struct(validFoo)
  729. }
  730. })
  731. }
  732. func BenchmarkStructSimpleFailure(b *testing.B) {
  733. validate := New()
  734. type Foo struct {
  735. StringValue string `validate:"min=5,max=10"`
  736. IntValue int `validate:"min=5,max=10"`
  737. }
  738. invalidFoo := &Foo{StringValue: "Fo", IntValue: 3}
  739. b.ResetTimer()
  740. for n := 0; n < b.N; n++ {
  741. _ = validate.Struct(invalidFoo)
  742. }
  743. }
  744. func BenchmarkStructSimpleFailureParallel(b *testing.B) {
  745. validate := New()
  746. type Foo struct {
  747. StringValue string `validate:"min=5,max=10"`
  748. IntValue int `validate:"min=5,max=10"`
  749. }
  750. invalidFoo := &Foo{StringValue: "Fo", IntValue: 3}
  751. b.ResetTimer()
  752. b.RunParallel(func(pb *testing.PB) {
  753. for pb.Next() {
  754. _ = validate.Struct(invalidFoo)
  755. }
  756. })
  757. }
  758. func BenchmarkStructComplexSuccess(b *testing.B) {
  759. validate := New()
  760. tSuccess := &TestString{
  761. Required: "Required",
  762. Len: "length==10",
  763. Min: "min=1",
  764. Max: "1234567890",
  765. MinMax: "12345",
  766. Lt: "012345678",
  767. Lte: "0123456789",
  768. Gt: "01234567890",
  769. Gte: "0123456789",
  770. OmitEmpty: "",
  771. Sub: &SubTest{
  772. Test: "1",
  773. },
  774. SubIgnore: &SubTest{
  775. Test: "",
  776. },
  777. Anonymous: struct {
  778. A string `validate:"required"`
  779. }{
  780. A: "1",
  781. },
  782. Iface: &Impl{
  783. F: "123",
  784. },
  785. }
  786. b.ResetTimer()
  787. for n := 0; n < b.N; n++ {
  788. _ = validate.Struct(tSuccess)
  789. }
  790. }
  791. func BenchmarkStructComplexSuccessParallel(b *testing.B) {
  792. validate := New()
  793. tSuccess := &TestString{
  794. Required: "Required",
  795. Len: "length==10",
  796. Min: "min=1",
  797. Max: "1234567890",
  798. MinMax: "12345",
  799. Lt: "012345678",
  800. Lte: "0123456789",
  801. Gt: "01234567890",
  802. Gte: "0123456789",
  803. OmitEmpty: "",
  804. Sub: &SubTest{
  805. Test: "1",
  806. },
  807. SubIgnore: &SubTest{
  808. Test: "",
  809. },
  810. Anonymous: struct {
  811. A string `validate:"required"`
  812. }{
  813. A: "1",
  814. },
  815. Iface: &Impl{
  816. F: "123",
  817. },
  818. }
  819. b.ResetTimer()
  820. b.RunParallel(func(pb *testing.PB) {
  821. for pb.Next() {
  822. _ = validate.Struct(tSuccess)
  823. }
  824. })
  825. }
  826. func BenchmarkStructComplexFailure(b *testing.B) {
  827. validate := New()
  828. tFail := &TestString{
  829. Required: "",
  830. Len: "",
  831. Min: "",
  832. Max: "12345678901",
  833. MinMax: "",
  834. Lt: "0123456789",
  835. Lte: "01234567890",
  836. Gt: "1",
  837. Gte: "1",
  838. OmitEmpty: "12345678901",
  839. Sub: &SubTest{
  840. Test: "",
  841. },
  842. Anonymous: struct {
  843. A string `validate:"required"`
  844. }{
  845. A: "",
  846. },
  847. Iface: &Impl{
  848. F: "12",
  849. },
  850. }
  851. b.ResetTimer()
  852. for n := 0; n < b.N; n++ {
  853. _ = validate.Struct(tFail)
  854. }
  855. }
  856. func BenchmarkStructComplexFailureParallel(b *testing.B) {
  857. validate := New()
  858. tFail := &TestString{
  859. Required: "",
  860. Len: "",
  861. Min: "",
  862. Max: "12345678901",
  863. MinMax: "",
  864. Lt: "0123456789",
  865. Lte: "01234567890",
  866. Gt: "1",
  867. Gte: "1",
  868. OmitEmpty: "12345678901",
  869. Sub: &SubTest{
  870. Test: "",
  871. },
  872. Anonymous: struct {
  873. A string `validate:"required"`
  874. }{
  875. A: "",
  876. },
  877. Iface: &Impl{
  878. F: "12",
  879. },
  880. }
  881. b.ResetTimer()
  882. b.RunParallel(func(pb *testing.PB) {
  883. for pb.Next() {
  884. _ = validate.Struct(tFail)
  885. }
  886. })
  887. }
  888. type TestOneof struct {
  889. Color string `validate:"oneof=red green"`
  890. }
  891. func BenchmarkOneof(b *testing.B) {
  892. w := &TestOneof{Color: "green"}
  893. val := New()
  894. for i := 0; i < b.N; i++ {
  895. _ = val.Struct(w)
  896. }
  897. }
  898. func BenchmarkOneofParallel(b *testing.B) {
  899. w := &TestOneof{Color: "green"}
  900. val := New()
  901. b.ResetTimer()
  902. b.RunParallel(func(pb *testing.PB) {
  903. for pb.Next() {
  904. _ = val.Struct(w)
  905. }
  906. })
  907. }