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

Optimization for ValueListOutput #573

Closed
CodingFabian opened this issue Jul 20, 2017 · 5 comments
Closed

Optimization for ValueListOutput #573

CodingFabian opened this issue Jul 20, 2017 · 5 comments
Labels
type: enhancement A general enhancement
Milestone

Comments

@CodingFabian
Copy link
Contributor

There are many cases where a ValueListOutput is used when the amount of returned values is known

like com.lambdaworks.redis.RedisCommandBuilder.zrange(K, long, long) will have stop-start and
com.lambdaworks.redis.RedisCommandBuilder.hmget(K, K...) will have keys.length

For that we could add a second constructor that takes an additional capacity argument for the array list. backwards compatible would be to use "10" as capacity.

what do you think?

@mp911de
Copy link
Collaborator

mp911de commented Jul 21, 2017

I think there's some potential to improve. Redis array responses contain the size in their header. When using streaming, outputs don't really require an eager initialization with ArrayList because the result is streamed to a Subscriber interface instead of the list.

It would make sense to distinguish and have a late initialization that either initializes ArrayList with the response size as soon as we receive the response or, for streaming, do not create ArrayList instances at all.

@mp911de mp911de added the type: enhancement A general enhancement label Jul 21, 2017
@mp911de mp911de added this to the Lettuce 4.4.0 milestone Jul 21, 2017
@CodingFabian
Copy link
Contributor Author

Good idea, the latter is what I did for our use case already as soon as I discovered it. I really like the layered API of lettuce, so I can easily choose convenience or maximum control and performance.

@mp911de
Copy link
Collaborator

mp911de commented Jul 23, 2017

Together with a few other optimizations (Returning Collections.emptyList() if array response is empty) we end up with the following benchmark:

4.4

Benchmark                                                     Mode  Cnt    Score    Error  Units
ValueListOutputBenchmark.measure100Elements                   avgt   40  444,795 ± 11,781  ns/op
ValueListOutputBenchmark.measure100ElementsWithResizeElement  avgt   40  568,426 ± 11,864  ns/op
ValueListOutputBenchmark.measure16Elements                    avgt   40   66,082 ±  1,858  ns/op
ValueListOutputBenchmark.measure16ElementsWithResizeElement   avgt   40  131,118 ±  2,453  ns/op
ValueListOutputBenchmark.measureSingleElement                 avgt   40   12,097 ±  0,482  ns/op
ValueListOutputBenchmark.measureZeroElement                   avgt   40    0,278 ±  0,005  ns/op

4.3

Benchmark                                                     Mode  Cnt    Score    Error  Units
ValueListOutputBenchmark.measure100Elements                   avgt   40  641,254 ± 58,630  ns/op
ValueListOutputBenchmark.measure100ElementsWithResizeElement  avgt   40  661,805 ± 51,144  ns/op
ValueListOutputBenchmark.measure16Elements                    avgt   40  144,651 ± 24,637  ns/op
ValueListOutputBenchmark.measure16ElementsWithResizeElement   avgt   40  144,673 ± 36,781  ns/op
ValueListOutputBenchmark.measureSingleElement                 avgt   40   13,783 ±  2,029  ns/op
ValueListOutputBenchmark.measureZeroElement                   avgt   40    6,893 ±  1,297  ns/op

mp911de added a commit that referenced this issue Jul 23, 2017
Lettuce now allocates lazily array output targets (Maps, ArrayList) with the appropriate size initialization. Optimize Subscriber to pass in the target to avoid ListSubscriber instances and convert it to a class for improved CHA/omit call-devirtualization.
mp911de added a commit that referenced this issue Jul 23, 2017
Lettuce now allocates lazily array output targets (Maps, ArrayList) with the appropriate size initialization. Optimize Subscriber to pass in the target to avoid ListSubscriber instances and convert it to a class for improved CHA/omit call-devirtualization.
@mp911de
Copy link
Collaborator

mp911de commented Jul 23, 2017

Done.

@mp911de mp911de closed this as completed Jul 23, 2017
@CodingFabian
Copy link
Contributor Author

Quite a nice speedup :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants