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

Stabilize secondary_super_cache in server code #10802

Merged

Conversation

lorban
Copy link
Contributor

@lorban lorban commented Oct 27, 2023

Fix the type pollution of the top two contenders on the server reported in #10781.

Removing the cast-to-interface in these two places boosts perf by a couple of %.

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
@lorban lorban requested review from gregw and sbordet October 27, 2023 15:59
@lorban lorban self-assigned this Oct 27, 2023
sbordet
sbordet previously approved these changes Oct 27, 2023
Copy link
Contributor

@gregw gregw left a comment

Choose a reason for hiding this comment

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

Wow! You'll have to explain this one to me sometime

Comment on lines 859 to 863
return (Request)super.getWrapped();
// Identical to (Request)super.getWrapped() except that the cast is costly here.
return request;
Copy link
Contributor

@gregw gregw Oct 27, 2023

Choose a reason for hiding this comment

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

We have similar code in

  • RetainableByteBuffer
  • ConnectionMetaData
  • ServerUpgradeRequestDelegate
  • ServerUpgradeResponseDelegate

Of these, maybe only RetainableByteBuffer may have any impact, but we should remove the anti-pattern from our code and avoid casting our wrapped types

Copy link
Contributor

Choose a reason for hiding this comment

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

It is a tradeoff between memory (we don't want to store the same reference in N fields, one of each wrapper), and this JDK issue, and so far it has only surfaced for Request, so I would not bother for the others.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we at least look at the usage of retainedbytebuffer wrapper, to see if applies at least a little bit

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Before generalizing this pattern, there's a 3rd contender on the list reported by the type pollution agent that should be looked at.

I did a quick analysis, and that 3rd one isn't going to be easy, as IMHO its root lies in a design mistake we made. Very briefly, the ExecutionStrategy.Producer should have specified Invocable.Task instead of plain Runnable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@sbordet FYI I analyzed the layout of Request.Wrapper in multiple conditions and found out that this extra field is costing 8 bytes in all conditions, making the heap consumption grow from 16 to 24 with G1 and Shenandoah and from 24 to 32 with Z because of compressed oops, padding and memory alignment.

Clearly, we're trading off memory for speed here.

Copy link
Contributor

@gregw gregw Oct 28, 2023

Choose a reason for hiding this comment

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

Note that it might be better to simply not use the Attributes.Wrapper base class. I do not think there is any situation that Request.Wrapper must be an Attributes.Wrapper. It can just implement the Attributes delegate methods itself. I think that is a small cost to pay for a space saving on every single request wrapper (and there may be multiple wrappers per real request).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed Request.Wrapper so it doesn't extend from Attributes.Wrapper anymore. This gives us the best of both worlds perf wise (i.e.: the speed boost and the best memory efficiency) in exchange of the minuscule usability cost of not being an Attributes.Wrapper and not being able to use Attributes.unwrap anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gregw RetainableByteBuffer.Wrapper isn't a problem, if only because it's only used by ArrayByteBufferPool.Tracking and tests. This is confirmed by the server report I attached in #10781.

@lorban
Copy link
Contributor Author

lorban commented Oct 28, 2023

@gregw We should definitely talk about this issue, and other vaguely related things I found out while working on it.

gregw
gregw previously approved these changes Oct 29, 2023
…utes.Wrapper

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
@lorban lorban dismissed stale reviews from gregw and sbordet via fbb1524 October 30, 2023 09:03
Signed-off-by: Ludovic Orban <lorban@bitronix.be>
@lorban lorban requested review from sbordet and gregw October 30, 2023 12:58
@lorban
Copy link
Contributor Author

lorban commented Oct 30, 2023

I can confirm the perf gain is real. This is worth nearly as much as our last perf improvement effort!

@lorban lorban changed the title Try to stabilize secondary_super_cache Try to stabilize secondary_super_cache in server code Oct 30, 2023
Copy link
Contributor

@sbordet sbordet left a comment

Choose a reason for hiding this comment

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

Just a couple of nits.

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
@lorban lorban requested a review from sbordet October 31, 2023 08:53
@lorban lorban added this to the 12.0.x milestone Oct 31, 2023
@lorban lorban changed the title Try to stabilize secondary_super_cache in server code Stabilize secondary_super_cache in server code Oct 31, 2023
@lorban lorban modified the milestone: 12.0.x Nov 1, 2023
@lorban lorban merged commit 5e747ac into jetty-12.0.x Nov 1, 2023
2 checks passed
@lorban lorban deleted the experiment/jetty-12-10781-type-pollution-reduction branch November 1, 2023 08:28
@franz1981
Copy link

I can confirm the perf gain is real. This is worth nearly as much as our last perf improvement effort!

Just curious; how much @lorban ? :D

@lorban
Copy link
Contributor Author

lorban commented Oct 28, 2024

@franz1981 from the top of my head, we got about a 2.5% perf boost overall.

@franz1981
Copy link

Thanks! So, measurable beyond noise but still small. If you want to use the latest commit of the agent I have added support for a new type of report which, in some cases, has delivered another for free boost i.e. MISS report.
I can explain here or to @sbordet what it is ;)

@lorban
Copy link
Contributor Author

lorban commented Oct 30, 2024

@franz1981 I'm always interested in good performance stories, so by any means please go ahead if you have the time to explain another discovery of yours.

I can't promise we'll look into it any time soon though, this performance exercise was done because we were looking to close the small gap between Jetty 10/11 and Jetty 12, and we stopped once all 3 versions achieved similar perf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

4 participants