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

Avoid allocating instances of AtomicReference in Uni #660

Closed
wants to merge 2 commits into from

Conversation

Sanne
Copy link
Contributor

@Sanne Sanne commented Aug 24, 2021

Under load in Quarkus, when profiling a Reactive application (RestEasy Reactive + Hibernate Reactive), I can see a significant amount of AtomicReference instances being allocated, as internal implementation of each UniOperatorProcessor.

In this PR I'm suggesting to refactor the AtomicReference to use an AtomicReferenceFieldUpdater.

The method names are a bit mouthful :) Any better suggestions? I'm patching code I don't know very well, so not sure how to call these.

@codecov
Copy link

codecov bot commented Aug 24, 2021

Codecov Report

Merging #660 (9be8567) into main (0bf24d9) will increase coverage by 0.24%.
The diff coverage is 90.00%.

Impacted file tree graph

@@             Coverage Diff              @@
##               main     #660      +/-   ##
============================================
+ Coverage     90.03%   90.28%   +0.24%     
- Complexity     3022     3035      +13     
============================================
  Files           395      395              
  Lines         11829    11833       +4     
  Branches       1478     1480       +2     
============================================
+ Hits          10650    10683      +33     
+ Misses          604      585      -19     
+ Partials        575      565      -10     
Impacted Files Coverage Δ
.../smallrye/mutiny/operators/uni/UniRetryAtMost.java 76.31% <50.00%> (ø)
...rye/mutiny/operators/uni/UniOperatorProcessor.java 80.76% <90.00%> (+3.49%) ⬆️
...mallrye/mutiny/operators/uni/UniFailOnTimeout.java 81.63% <100.00%> (ø)
...allrye/mutiny/operators/uni/UniOnCancellation.java 84.00% <100.00%> (ø)
...ye/mutiny/operators/uni/UniOnCancellationCall.java 75.75% <100.00%> (ø)
...lrye/mutiny/operators/uni/UniOnFailureFlatMap.java 80.00% <100.00%> (ø)
...utiny/operators/uni/UniOnItemOrFailureFlatMap.java 87.80% <100.00%> (ø)
.../mutiny/operators/uni/UniOnItemTransformToUni.java 83.33% <100.00%> (ø)
...perators/multi/processors/SerializedProcessor.java 88.11% <0.00%> (-4.96%) ⬇️
...mallrye/mutiny/operators/multi/MultiFlatMapOp.java 85.98% <0.00%> (+0.93%) ⬆️
... and 8 more

Copy link
Contributor

@cescoffier cescoffier left a comment

Choose a reason for hiding this comment

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

LGTM,

I tried to avoid field updater to avoid the cost in native (at some point it was adding every classes having a field updater even if not used - that was quite a long time ago when I started Mutiny).

I'm not concerned by this with your changes, as anyway we need this class every time.

@Ladicek
Copy link
Contributor

Ladicek commented Aug 25, 2021

Mutiny is still on Java 8, right? Otherwise we could use VarHandles, which are supposed to be faster than AtomicField*Updaters (at least that's what I heard, I don't really know :-) ).

@cescoffier
Copy link
Contributor

@Ladicek for now, yes... Java 8. For how long? That's a topic I'm working on currently (not on the technical side).

Now that varhandle are supported in native executable, that would be very interesting to compare.

@Sanne
Copy link
Contributor Author

Sanne commented Aug 25, 2021

Right, in fact I had started my first experiment with VarHandle only to then figure out it wouldn't be Java 8 compatible :)

I briefly considered multi-release jars, but the effort of introducing that in the project (and wondering if it would be welcome?) put me off. After all the problem I'm solving here is allocations, and this is effective towards that goal.

Having the internals now encapsulated, it should be trivial to switch later on.

@jponge
Copy link
Member

jponge commented Aug 27, 2021

Method names are fine, and we can always refactor since it's all internal APIs :-)

@jponge
Copy link
Member

jponge commented Aug 27, 2021

It's safe to have an iteration to reduce allocation (granted performance remains flat) with atomic field updaters, and then in the future we can do another iteration to investigate VarHandle when it will be fine to be Java 11+.

@jponge jponge mentioned this pull request Aug 27, 2021
3 tasks
@jponge jponge changed the title Avoid allocating instances of AtomicReference Avoid allocating instances of AtomicReference in Uni Aug 27, 2021
@jponge jponge linked an issue Aug 27, 2021 that may be closed by this pull request
3 tasks
@jponge jponge removed a link to an issue Aug 27, 2021
3 tasks
@jponge
Copy link
Member

jponge commented Aug 27, 2021

Part of #666 epic

@jponge
Copy link
Member

jponge commented Aug 27, 2021

(the fact that the epic has number 666 is pure coincidence)

@jponge jponge added enhancement New feature or request technical-debt Technical debt reduction labels Aug 27, 2021
@jponge
Copy link
Member

jponge commented Aug 27, 2021

So let's have #666 has an epic to reduce allocations in Mutiny, and let's have this PR to cover all Uni cases.

I'll have a look next week at your branch @Sanne, and dig for missing places.

@jponge
Copy link
Member

jponge commented Aug 30, 2021

Starting work, rebasing, I'll push force over here if need be

@jponge
Copy link
Member

jponge commented Aug 30, 2021

@Sanne I've done a few minor additions for Uni, see jponge@bde89f2 but the most important improvements are in your commits.

I did not blindly go through all places in Uni, just where it made sense to me right now.

@jponge
Copy link
Member

jponge commented Aug 30, 2021

@Sanne you might cherry-pick that commit, I can't push to your branch

@jponge
Copy link
Member

jponge commented Aug 31, 2021

#669 is a clean branch, also includes @MarkMarkyMarkus remark

@Sanne
Copy link
Contributor Author

Sanne commented Aug 31, 2021

Nice, should we close this PR?

@jponge
Copy link
Member

jponge commented Aug 31, 2021

Yes :-)

@jponge jponge closed this Aug 31, 2021
@Sanne Sanne deleted the MemoryOptimisations branch August 31, 2021 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request technical-debt Technical debt reduction
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants