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

[java-generator] performance improvementes #4867

Merged
merged 10 commits into from
Feb 14, 2023
Merged

Conversation

mariofusco
Copy link
Contributor

@mariofusco mariofusco commented Feb 10, 2023

Fix #4865

This PR:

  • replaces some wasteful hidden invocations to StaticJavaParser.parseClassOrInterfaceType with explicit javaparser AST nodes constructors
  • splits the code generation and writing phases
  • performs the writings in independent async tasks

Copy link
Member

@andreaTP andreaTP left a comment

Choose a reason for hiding this comment

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

Amazing job @mariofusco 🎉 🚀 🚀 🚀
Thanks a ton!!!

A minor style nitpick and it's good to go.
Can you share the perf difference before/after this change?


int i = 0;
for (WritableCRCompilationUnit w : wCUs) {
futures[i++] = CompletableFuture.runAsync(() -> w.writeAllJavaClasses(basePath));
Copy link
Member

Choose a reason for hiding this comment

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

Have you attempted to use a different Thread Pool than the ForkJoinPool.commonPool since it's used also by the underlying parallelStreams?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At that point the code generation performed in the parallel stream is finished and that pool should be completely available to write files. Also consider that creating a brand new thread pool could be very likely much more expansive than writing the file, that's why imo it is a better idea to reuse an already existing pool. Anyway if we had the JMH benchmark that I'm proposing in the other comment we could properly measure this.

Copy link
Member

Choose a reason for hiding this comment

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

You can find the yaml I was using here: https://github.com/kserve/kserve/releases/download/v0.10.0/kserve.yaml
feel free to add it to the CompilationTest along with this PR.

Feel free to add a JMH benchmark if you think that it's useful, but I'm convinced that this PR is perfectly enough for a first iteration.
In case performance issues becomes a problem we can revisit the implementation later on 👍

Thanks again!

private void writeCRCompilationUnits(File basePath, List<WritableCRCompilationUnit> wCUs) {
CompletableFuture<Void>[] futures = new CompletableFuture[wCUs.size()];

int i = 0;
Copy link
Member

Choose a reason for hiding this comment

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

[nitpick] can you, please, move wCUs.size() to a val (e.g. total) and reuse it as a boundary in the following for loops?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

CompletableFuture<Void>[] futures = new CompletableFuture[wCUs.size()];

int i = 0;
for (WritableCRCompilationUnit w : wCUs) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
for (WritableCRCompilationUnit w : wCUs) {
for (int i = 0; i < total; i++) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

futures[i++] = CompletableFuture.runAsync(() -> w.writeAllJavaClasses(basePath));
}

for (int j = 0; j < futures.length; j++) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
for (int j = 0; j < futures.length; j++) {
for (int j = 0; j < total; j++) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@mariofusco
Copy link
Contributor Author

Can you share the perf difference before/after this change?

In reality I can no longer run my main because I don't have anymore the yaml that I was using to test it. Is it possible to push it on main or somewhere else? That said I'm afraid that the code generation triggered by that file doesn't last long enough to see any reliably measurable difference. Maybe we could find a bigger test case and put it in a JMH benchmark?

@mariofusco
Copy link
Contributor Author

I added a JMH benchmark to demonstrate the performance improvement of this PR and got the following results.

Before this PR:

Benchmark                                 Mode  Cnt  Score   Error  Units
SourceCodeGenerationBenchmark.benchmark  thrpt   10  1.451 ± 0.036  ops/s

After

Benchmark                                 Mode  Cnt  Score   Error  Units
SourceCodeGenerationBenchmark.benchmark  thrpt   10  2.845 ± 0.201  ops/s

Copy link
Member

@andreaTP andreaTP left a comment

Choose a reason for hiding this comment

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

Amazing job @mariofusco , good to go! 🎉

Copy link
Member

@manusa manusa left a comment

Choose a reason for hiding this comment

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

LGTM, thx!

Awesome job 🙌

@manusa manusa added this to the 6.5.0 milestone Feb 13, 2023
@sonarcloud
Copy link

sonarcloud bot commented Feb 14, 2023

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

71.0% 71.0% Coverage
0.0% 0.0% Duplication

@manusa manusa merged commit d6967f9 into fabric8io:master Feb 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve performance of the java-generator
4 participants