Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance optimizations #16

Open
typerandom opened this issue May 2, 2015 · 2 comments
Open

Performance optimizations #16

typerandom opened this issue May 2, 2015 · 2 comments

Comments

@typerandom
Copy link
Owner

Up until now focus have been on API design and features and not on performance/memory usage. So as you can see in the benchmark below, the library is currently outperformed by it's competitors (Edit: Worth nothing that this is no longer the case. See latest bench in comments.). Though this should not be that hard to fix.

Name                                            Runs        Time spent      Memory
-----------------------------------------------------------------------------------------------------------
BenchmarkNativeMin                              20000000    111 ns/op       34 B/op        2 allocs/op
BenchmarkValidatorMin                           200000      11590 ns/op     3100 B/op      88 allocs/op
BenchmarkCompetitorGoValidatorMin               200000      8998 ns/op      2100 B/op      66 allocs/op
BenchmarkCompetitorAsaskevichGoValidatorMin     5000000     672 ns/op       32 B/op        2 allocs/op

Things I know that are unnecessarily expensive:

  • Parsing structure tags - Could easily be cached. (implemented)
  • Walking structure fields - At this moment the whole structure graph is traversed. Could be minimized to fields with the validate tag. Of course, worsens user experience.
  • Normalization - Normalizing values to their 64-bit counterparts and dereferencing values/passing copies and turning nil values into their "zero" structures is expensive. Should do some benchmarking to see exactly how expensive it is.

Another optimization that could be done is to build a validation graph for each structure type so that one would not have to walk the whole struct graph all of the time.

typerandom added a commit that referenced this issue May 7, 2015
@typerandom
Copy link
Owner Author

Just added cache for reflected fields, and performance is up from 11590 ns/op to 4324 ns/op and from 88 allocs/op to 26 allocs/op. Lookin' good!

Name                                            Runs        Time spent      Memory
-----------------------------------------------------------------------------------------
BenchmarkNativeMin                              20000000    117 ns/op       34 B/op        2 allocs/op
BenchmarkValidatorMin                           500000      4324 ns/op      889 B/op          26 allocs/op
BenchmarkCompetitorGoValidatorMin               200000      8510 ns/op      2103 B/op         66 allocs/op
BenchmarkCompetitorAsaskevichGoValidatorMin     5000000     610 ns/op       32 B/op        2 allocs/op

@typerandom
Copy link
Owner Author

Improved memory use slightly by changing the way that errors were created.

Name                                            Runs        Time spent      Memory
-----------------------------------------------------------------------------------------
BenchmarkNativeMin                              20000000    117 ns/op       34 B/op        2 allocs/op
BenchmarkValidatorMin                           500000      4143 ns/op      788 B/op          22 allocs/op
BenchmarkCompetitorGoValidatorMin               200000      9134 ns/op      2103 B/op         66 allocs/op
BenchmarkCompetitorAsaskevichGoValidatorMin     5000000     643 ns/op       32 B/op        2 allocs/op

@typerandom typerandom added this to the Stable release milestone May 14, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant