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

Reviewed some Quarkus core classes #40630

Merged
merged 3 commits into from
May 15, 2024
Merged

Conversation

Sanne
Copy link
Member

@Sanne Sanne commented May 14, 2024

As I was profiling the bootstrap process, I spotted some small inefficiencies and a couple of potential bugs.
Best reviewed by individual commits, as each change is independent - wrapped together as they are all very small changes.

@Sanne Sanne requested a review from geoand May 14, 2024 13:31
Copy link
Contributor

@geoand geoand left a comment

Choose a reason for hiding this comment

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

Very nice!

Comment on lines +35 to +36
IGNORED_PROPERTY_ANNOTATIONS = ignoredPropertyAnnotations.toArray(new Class[0]);
RECORDABLE_CONSTRUCTOR_ANNOTATIONS = recordableConstructorAnnotations.toArray(new Class[0]);
Copy link
Contributor

Choose a reason for hiding this comment

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

As we're making things more efficient, we can make new Class[0] a constant, no?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd say it's unnecessary - compiler knows this pattern well. Also, any static constant takes memory forever :P

Copy link
Contributor

Choose a reason for hiding this comment

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

compiler knows this pattern well

kk

@@ -43,7 +43,7 @@ public Property[] apply(Class<?> type) {
if (existingGetter == null || existingGetter.getReturnType().isAssignableFrom(i.getReturnType())) {
getters.put(name, i);
}
} else if (i.getName().startsWith("is") && i.getName().length() > 3 && i.getParameterCount() == 0
} else if (i.getName().startsWith("is") && i.getName().length() > 2 && i.getParameterCount() == 0
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

static final ConcurrentMap<Class<?>, Property[]> CACHE = new ConcurrentHashMap<>();

private static final Function<Class<?>, Property[]> FUNCTION = new Function<Class<?>, Property[]>() {
private static final ClassValue<Property[]> CACHE = new ClassValue<Property[]>() {
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

Copy link
Member Author

Choose a reason for hiding this comment

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

N.B. I'm not sure the original code would leak, but this seems much safer to me. I'm referring to classloader leaks in case there's a recorder triggered as this is only capturing properties of recorders so I don't think it would happen.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yup

@Sanne Sanne force-pushed the CoreSimplifications branch from f682f4f to 92e5a67 Compare May 14, 2024 16:03

public FieldsHelper(final Class<?> aClass) {
final Field[] declaredFields = aClass.getDeclaredFields();
this.fields = new HashMap<>(declaredFields.length);
Copy link
Member

Choose a reason for hiding this comment

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

Not sure it's a good idea to do that, your Map will be resized always given the default loadFactor of 0.75.

In HV, we had a util who correctly created a Map of the right size for all the maps initialized at bootstrap: https://github.com/hibernate/hibernate-validator/blob/729cd018599d046aa5db1dbe35700521dd596c4e/engine/src/main/java/org/hibernate/validator/internal/util/CollectionHelper.java#L142-L147 .

And sure, it's a micro optimization but in your case, you might create more harm than none by always sizing the map a bit too small.

Copy link
Member Author

Choose a reason for hiding this comment

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

what are you suggesting, would you prefer I simply use new HashMap<>(); ?

FWIW I know about the optimisation in Validator and we had a similar thing in ORM, but it's not taking into account the likelyhood of hash collisions.. that's why there is a load factor in the hashmap implementation: it's hard to estimate perfectly. One could argue that the default loadfactor is a bit low.. My rule of thumb is currently that as long as we resize just a couple times it's fine, so I like passing the estimated size (when we have it) so to have it right at least within order of magnitude. I guess since in this case we expect the lifespan of the map to be short one should rather overestimate: I'll shift it right once so to double its size?

Copy link
Member Author

Choose a reason for hiding this comment

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

BTW just checked, on recent JVMs the HashMap implementation is different and it looks like that this is no longer a problem.

Might be time to simplify Validator as well :)

This comment has been minimized.

@Sanne
Copy link
Member Author

Sanne commented May 14, 2024

Something seems way off .. I'll need to separate these.

@Sanne Sanne force-pushed the CoreSimplifications branch from 92e5a67 to ad96389 Compare May 14, 2024 21:21
Copy link

quarkus-bot bot commented May 15, 2024

Status for workflow Quarkus CI

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

✅ 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.


Flaky tests - Develocity

⚙️ JVM Tests - JDK 17 Windows

📦 integration-tests/grpc-hibernate

com.example.grpc.hibernate.BlockingRawTest.shouldAdd - History

  • Condition with Lambda expression in com.example.grpc.hibernate.BlockingRawTestBase was not fulfilled within 30 seconds. - org.awaitility.core.ConditionTimeoutException
org.awaitility.core.ConditionTimeoutException: Condition with Lambda expression in com.example.grpc.hibernate.BlockingRawTestBase was not fulfilled within 30 seconds.
	at org.awaitility.core.ConditionAwaiter.await(ConditionAwaiter.java:167)
	at org.awaitility.core.CallableCondition.await(CallableCondition.java:78)
	at org.awaitility.core.CallableCondition.await(CallableCondition.java:26)
	at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:1006)
	at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:975)
	at com.example.grpc.hibernate.BlockingRawTestBase.shouldAdd(BlockingRawTestBase.java:59)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)

@Sanne
Copy link
Member Author

Sanne commented May 15, 2024

I had it run again after removing the one fix which was introducing the ClassValue, and it's passing now. So I'll merge these and scrutinize my understanding of ClassValue ..

@Sanne Sanne merged commit 821e889 into quarkusio:main May 15, 2024
51 checks passed
@quarkus-bot quarkus-bot bot added this to the 3.11 - main milestone May 15, 2024
@geoand
Copy link
Contributor

geoand commented May 15, 2024

Very weird... I'd like to know why ClassValue was problems, if anything I expected to be better :)

@Sanne Sanne deleted the CoreSimplifications branch May 15, 2024 08:20
@Sanne
Copy link
Member Author

Sanne commented May 15, 2024

Very weird... I'd like to know why ClassValue was problems, if anything I expected to be better :)

Same. I'll send a PR with that change individually - should have done so from the beginning but didn't want to flood CI (and reviewers) with all the noise from small changes.

#40651

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.

3 participants