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

[rest.li] Update SimpleLoadBalancer to use for loop instead of Map #947

Merged
merged 2 commits into from
Nov 27, 2023

Conversation

vshwnth2
Copy link
Contributor

[rest.li] Update SimpleLoadBalancer to use for loop instead of Map

When running ODP analysis, we observed that SimpleLoadBalancer.getPotentialClients map collect uses around 4% CPU. Much of this seems Collector.toMap's uniqKeysMapAccumulator. In this scenario, this is performing unnecessary extra computation -- the keys of the Map we are creating come directly from a Set.

The updated implementation avoids the stream(...).collect(Collectors.toMap(...) and directly uses a for loop to populate the Map

252851489-1cc65047-d39b-4f34-888f-b98e5f000d03

Copy link
Member

@PapaCharlie PapaCharlie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

.collect(Collectors.toMap(
uri -> uri,
uri -> uris.getPartitionDataMap(uri).get(partitionId).getWeight()));
Map<URI, Double> weightedUris = new HashMap<>(possibleUris.size());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have a util to calculate the map size according to the load factor? this is to prevent map resizes

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JDK assume standard 66%, so if we want to optimize it to the max and avoid hash collisions and collision chains we can divide possibleUris size by 0.66 and round up to the nearest integer

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you preallocate the map size like this you dramatically reduce the odds of a resize during the insertion. It's still possible you'd get a resize if for whatever reason there were many hash collisions, but you can't really do anything about that anyway, even if you took into account the default load factor. I guess the only way to truly prevent a resize is to use an ImmutableMap.builder from guava which lazily creates the backing map

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doubt possibleURIs has hundreds of thousands or millions of elements. I expect <1K, thus chance of URI hash collisions is very low, and thus map size equal to collection size should work fine ;)

@PapaCharlie PapaCharlie merged commit 299326f into linkedin:master Nov 27, 2023
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants