Skip to content

Improved Meter.Id#getTags() performance #6182

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

etki
Copy link

@etki etki commented Apr 26, 2025

Hey. This is a very small and simple PR aimed at a tiny performance improvement: currently, the .getTags() call always allocates a zero-sized array list and then uses a .forEach call (which results in allocating another object for lambda, and, in the worst case, non-inlined call) to populate it. PR checks if list is needed at all, and if so, asks for a list with a space for 32 elements, populating it in a classic loop. The number of 32 is only a guess with no real grounds.

This is definitely not the biggest problem around, so the change is perceptible, yet not a game changer.

Benchmarks from #6174 and Intel N100 fixed at 2GHz were used to estimate the impact. The benchmark uses identifiers with 0-64 tags, where the number of tags in the mode column occurs 90% of time, and other values are distributed evenly in the remaining space.

mode version ns/op instructions/op
0 main 43.379 ± 0.056 284.221
0 PR 44.352 ± 0.782 263.863
1 main 71.544 ± 0.188 499.757
1 PR 65.575 ± 0.480 397.938
2 main 81.493 ± 0.704 567.298
2 PR 72.908 ± 1.048 456.693
4 main 92.932 ± 0.451 669.917
4 PR 82.054 ± 1.028 552.133
8 main 120.026 ± 1.511 879.752
8 PR 104.113 ± 1.794 742.707
16 main 209.666 ± 2.159 1532.392
16 PR 143.756 ± 3.422 995.800
32 main 345.139 ± 3.130 2525.301
32 PR 244.574 ± 7.125 1921.113
64 main 618.301 ± 6.336 4458.226
64 PR 496.224 ± 14.074 3775.938

Please note that some improvements suggested in #6113 (using Collections.unmodifiableList(Arrays.asList(...).subList(...) or even creating a custom List implementation that would combine all the three) will likely bring these numbers down to tens of ns per call on arrays of any length and make this PR completely redundant.

@@ -282,8 +282,14 @@ public String getName() {
* @return A set of dimensions that allows you to break down the name.
*/
public List<Tag> getTags() {
List<Tag> tags = new ArrayList<>();
this.tags.forEach(tags::add);
if (this.tags == Tags.empty()) {
Copy link
Author

Choose a reason for hiding this comment

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

It would be better to explicitly check for zero length, as it's possible to construct another instance with zero tags, but we don't have that API.

return Collections.emptyList();
}

List<Tag> tags = new ArrayList<>(32);
Copy link
Author

Choose a reason for hiding this comment

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

As stated above, 32 is purely a guess and is a subject for discussion

@etki etki force-pushed the meter-get-tags-performance-improvement branch from 674a6e4 to b3fa190 Compare April 26, 2025 08:29
@jonatan-ivanov jonatan-ivanov added the performance Issues related to general performance label Apr 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Issues related to general performance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants