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

Speedup Hibernate ORM's enhancement of large models #40329

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

Conversation

Sanne
Copy link
Member

@Sanne Sanne commented Apr 28, 2024

This works far better, in my local tests.

I feel it's ready, but it will require a fix on the ORM side to be merged first:

This brings enhancement times of the large model provided as benchmark down to ~1 second, without enabling Quarkus's caching capabilities of caching enhancement of unmodified classes (which we should also enable, but it's a separate aspect)

@quarkus-bot
Copy link

quarkus-bot bot commented Apr 28, 2024

/cc @gsmet (hibernate-orm), @yrodiere (hibernate-orm)

Copy link
Member

@yrodiere yrodiere left a comment

Choose a reason for hiding this comment

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

Thanks!

Seems safe to me, and it's great if it speeds things up so much, but could you please add a few comments? I'm afraid it's not as obvious for us as it is for you :)

@Sanne
Copy link
Member Author

Sanne commented Apr 29, 2024

Updated to add the suggested comments; also now registering the Panache super types as "core types" so they'd also benefit from caching, if used.

@Sanne
Copy link
Member Author

Sanne commented Apr 29, 2024

also now registering the Panache super types as "core types" so they'd also benefit from caching, if used.

Note to self: this implies that if we have live-reload tests in Panache which have entities using the same package name as Panache itself they might fail now for the silly reason of us skipping the work on such classes.

@Sanne Sanne force-pushed the BBSpeedup65 branch 2 times, most recently from c51be54 to e1bb761 Compare April 30, 2024 14:10
@Sanne
Copy link
Member Author

Sanne commented Apr 30, 2024

We decided to use:
"jakarta.persistence.", "java.", "org.hibernate.annotations.", "io.quarkus.hibernate.reactive.panache.", "io.quarkus.hibernate.orm.panache.", "org.hibernate.search.mapper.pojo.mapping.definition.annotation.", "jakarta.validation.constraints."

TODO: check this doesn't break Panache integration tests as they might be running under the same package name.

@Sanne
Copy link
Member Author

Sanne commented May 13, 2024

Rebased: simplified implementation taking advantage of eb69d59

@Sanne Sanne marked this pull request as ready for review May 16, 2024 08:40
@Sanne
Copy link
Member Author

Sanne commented May 16, 2024

Ok this is ready now, it was waiting for ORM 6.5.1.

Copy link
Member

@yrodiere yrodiere left a comment

Choose a reason for hiding this comment

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

Thanks. LGTM, just a small doubt that there might be an obsolete comment.

@quarkus-bot

This comment has been minimized.

@quarkus-bot

This comment has been minimized.

@Sanne
Copy link
Member Author

Sanne commented May 17, 2024

Please don't merge - I've pushed an experiment and need CI feedback.

@quarkus-bot

This comment has been minimized.

@yrodiere yrodiere changed the title Speedup Hibernate ORM's enhancement of large models [WIP] Speedup Hibernate ORM's enhancement of large models May 17, 2024
@quarkus-bot

This comment has been minimized.

@Sanne
Copy link
Member Author

Sanne commented May 20, 2024

@yrodiere I understand what's going on now, unfortunatley sharing the ByteBuddy caches would require much more work - and is tricky.

So I suggest we merge this version: it shares the caches of "core types" (which we know are not being modified) but isolates the caches used for bytecode enhancement in threadlocals to ensure independent interactions. It also shared the Enhancer implementation across runs, and makes its initialization lazy.

It's taking the safer approach - there's room for improvement as this forces each thread to repeat quite some work, and also allocate large structures w/o sharing those, but that would require much more work to share them safely, so I'd rather take the 80% improvement now and keep it safe until we have time to add more stricter integration tests.

Ok to merge? I'd hit the button as it's already approved, but since several changes were made...

@quarkus-bot
Copy link

quarkus-bot bot commented May 20, 2024

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit 138115a.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.

@Sanne Sanne changed the title [WIP] Speedup Hibernate ORM's enhancement of large models Speedup Hibernate ORM's enhancement of large models May 20, 2024
@mapuci
Copy link

mapuci commented May 20, 2024

offtopic:

@Sanne could you please take a look at this issue? It is kindof related to what you are doing here :)
#40719
There is something wrong with enhanced classes or even their classloaders...(in quarkus 2 and 3, but not in wildfly).
Reproducer repo contains enhanced .class files, so you can take a look at them.

I tried to reproduce problem with this branch, there is still a bug.

Copy link
Member

@yrodiere yrodiere left a comment

Choose a reason for hiding this comment

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

I'm really not sure using threadlocals without ever clearing them is safe in dev mode, but I'll let you check that, and merge if you are confident.


@Override
public void clear() {
//not useful
Copy link
Member

Choose a reason for hiding this comment

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

You could clear the thread-local? Maybe that's not the best place to do this, but it would be nice to at least try... somewhere...

We've been bitten by classloader leaks caused by threadlocals in the past... And it can get quite bad.

Comment on lines +112 to +114
final ThreadLocal<EnhancerClassLocator> localLocator = ThreadLocal
.withInitial(() -> ModelTypePool.buildModelTypePool(QuarkusClassFileLocator.INSTANCE,
CORE_POOL));
Copy link
Member

Choose a reason for hiding this comment

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

This threadlocal isn't static -- is this on purpose?

From what I can see ThreadsafeLocator is, in practice, a singleton, so using static here would make threadlocal cleanup easier. You know, where we restart in dev mode, drop half the classloaders but keep the same threads, resulting in threadlocals piling up...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants