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
Further performance improvements in link creation #1148
Milestone
Comments
odrotbohm
changed the title
Further improvements in link creation
Further performance improvements in link creation
Dec 6, 2019
odrotbohm
added a commit
that referenced
this issue
Dec 6, 2019
The implementation details of WebHandler have been significantly refactored to rather work with structures that allow better cacheability by clearly separating abstractions over the statically available information from the per-invocation aspects. This results in a new HandlerMethodParameter(s) abstraction within WebHandler. BoundMethodParameter has been removed entirely. HandlerMethodParameters are create once then cached for every controller method being linked to. DummyInvocationUtils now creates a ThreadLocal cache of the proxies created for calls to methodOn(…) as they essentially only act as basis for subsequent calls to the methods on the proxy created which in turn are expected to be handed into a linkTo(…) call which obtains the invocation right away. This avoids overhead in cases methodOn(…) is called multiple times for the same controller from a single controller. The lookup of the LastInvocationAware was previously routed through the proxy, handled by InvocationRecordingMethodInterceptor. This resulted in a second, reflective call for every link creation. DummyInvocationUtils now provides a dedicated lookup method as it knows about the structure of the proxy it created and thus can unfold the recorded invocation more effectively. The LinkBuilder type hierarchy now works with UriComponents and only creates a UriComponentsBuilder if it needs to modify the backing link in the first place. This avoids superfluous back and forth between UriComponents and UriComponentsBuilders that involved quite a bit of String parsing and creation. EncodingUtils now starts from a StandardCharsets.UTF_8 to avoid repeated Charset creation. The changes result in a ~3x performance compared to 1.0.2.RELEASE: 1.0.2.RELEASE Benchmark Mode Cnt Score Error Units ControllerLinkBuilderBenchmark.noLinkCreation thrpt 10 39004583,189 ± 751668,181 ops/s ControllerLinkBuilderBenchmark.pureLinkCreation thrpt 10 43443,133 ± 783,120 ops/s ControllerLinkBuilderBenchmark.withLinkCreation thrpt 10 60201,629 ± 1292,179 ops/s 1.1 / 1.0.3 SNAPSHOT Benchmark Mode Cnt Score Error Units ControllerLinkBuilderBenchmark.noLinkCreation thrpt 10 39618560,950 ± 612794,310 ops/s ControllerLinkBuilderBenchmark.pureLinkCreation thrpt 10 121700,634 ± 1510,415 ops/s ControllerLinkBuilderBenchmark.withLinkCreation thrpt 10 121982,085 ± 3344,206 ops/s noLinkCreation - creates a single RepresentationModel instance but adds no links pureLinkCreation - creates a single link pointing to a controller method withLinkCreation - creates a single RepresentationModel instance adding a single link
odrotbohm
added a commit
that referenced
this issue
Dec 6, 2019
The implementation details of WebHandler have been significantly refactored to rather work with structures that allow better cacheability by clearly separating abstractions over the statically available information from the per-invocation aspects. This results in a new HandlerMethodParameter(s) abstraction within WebHandler. BoundMethodParameter has been removed entirely. HandlerMethodParameters are create once then cached for every controller method being linked to. DummyInvocationUtils now creates a ThreadLocal cache of the proxies created for calls to methodOn(…) as they essentially only act as basis for subsequent calls to the methods on the proxy created which in turn are expected to be handed into a linkTo(…) call which obtains the invocation right away. This avoids overhead in cases methodOn(…) is called multiple times for the same controller from a single controller. The lookup of the LastInvocationAware was previously routed through the proxy, handled by InvocationRecordingMethodInterceptor. This resulted in a second, reflective call for every link creation. DummyInvocationUtils now provides a dedicated lookup method as it knows about the structure of the proxy it created and thus can unfold the recorded invocation more effectively. The LinkBuilder type hierarchy now works with UriComponents and only creates a UriComponentsBuilder if it needs to modify the backing link in the first place. This avoids superfluous back and forth between UriComponents and UriComponentsBuilders that involved quite a bit of String parsing and creation. EncodingUtils now starts from a StandardCharsets.UTF_8 to avoid repeated Charset creation. The changes result in a ~3x performance compared to 1.0.2.RELEASE: 1.0.2.RELEASE Benchmark Mode Cnt Score Error Units ControllerLinkBuilderBenchmark.noLinkCreation thrpt 10 39004583,189 ± 751668,181 ops/s ControllerLinkBuilderBenchmark.pureLinkCreation thrpt 10 43443,133 ± 783,120 ops/s ControllerLinkBuilderBenchmark.withLinkCreation thrpt 10 60201,629 ± 1292,179 ops/s 1.1 / 1.0.3 SNAPSHOT Benchmark Mode Cnt Score Error Units ControllerLinkBuilderBenchmark.noLinkCreation thrpt 10 39618560,950 ± 612794,310 ops/s ControllerLinkBuilderBenchmark.pureLinkCreation thrpt 10 121700,634 ± 1510,415 ops/s ControllerLinkBuilderBenchmark.withLinkCreation thrpt 10 121982,085 ± 3344,206 ops/s noLinkCreation - creates a single RepresentationModel instance but adds no links pureLinkCreation - creates a single link pointing to a controller method withLinkCreation - creates a single RepresentationModel instance adding a single link
With the fixes applied to Spring Framework's encoding classes we see the benchmark numbers improving by another 5-8%. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Follow up ticket for #698.
The text was updated successfully, but these errors were encountered: