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

Performance issues #100

Closed
pweso opened this issue Sep 7, 2021 · 11 comments
Closed

Performance issues #100

pweso opened this issue Sep 7, 2021 · 11 comments

Comments

@pweso
Copy link

pweso commented Sep 7, 2021

Hi,
as we are stuck with Java 8 my team has found your project very interesting. We’ve already tried Jabel on local envs and results were very promising. Although Java 8+ features, debugging and stack traces were fine there’s an issue we face: performance.
Our project is a modular monolith. Complication time (pure javac) jumped from 3 minutes to about 40 minutes. We did instrumentation with JProfiler and although execution times are inflated than with regular sampling, but it’s all about the number of calls.
We think the source of the problem is in make() method invocation.

visitors.forEach((className, visitor) -> {
    byteBuddy
            .redefine(
                    typePool.describe(className).resolve(),
                    classFileLocator
            )
            .visit(visitor)
            .make()
            .load(classLoader, ClassReloadingStrategy.fromInstalledAgent());
});

Do you have any tips to improve performance? We suspect that Jabel is also compiling third-party libraries of our project. Maybe there would be an option to add exclusions for such libraries? Or maybe the problem is in the byte-buddy library and library with better performance is worth considering?
Thanks!

Zrzut ekranu 2021-09-7 o 11 45 44
Zrzut ekranu 2021-09-7 o 11 38 55
Zrzut ekranu 2021-09-7 o 11 48 47

@bsideup
Copy link
Owner

bsideup commented Sep 7, 2021

Hi @pweso,

Thanks for doing the analysis! That's unfortunate - I will definitely look into.

It does look like something we may want to fix on the ByteBuddy side (cc @raphw), unless I am abusing the call, and maybe Rafael could share how it can be improved :)

@raphw
Copy link

raphw commented Sep 7, 2021

Hierarchy resolution is expensive as it is complex. Since you are only decorating and not overriding methods, consider using decorate and not redefine snd use MethodGraph.Compiler.ForDeclaredMethods.INSTANCE in the ByteBuddy configuration.

@bsideup
Copy link
Owner

bsideup commented Sep 7, 2021

@raphw many thanks! I will give it a try 👍

bsideup added a commit that referenced this issue Sep 7, 2021
@bsideup
Copy link
Owner

bsideup commented Sep 7, 2021

@raphw Interesting! Your suggestion works with Liberica but breaks with Adopt 😅

#101 in case you want to try it yourself (not expecting you to do so but I know that you're a curious developer 😁)

@raphw
Copy link

raphw commented Sep 7, 2021

decorate is not the most important change. Using the method graph compiler likely is.

@bsideup
Copy link
Owner

bsideup commented Sep 7, 2021

@raphw after move testing, it seems that method graph makes a very little difference, but decorate is what makes it fast for me. I also tried to measure individual visitors and it looks like MemberSubstitution has a major (3x) impact on the compilation speed. Can it be that, when decorate is used, it is not running hence the speed bump on Liberica?

@raphw
Copy link

raphw commented Sep 7, 2021

No, decorate should allow exactly that. Decorate byte code but without resolving the hierarchy of super classes. I never heard of individual builds failing. I run Byte Buddy on adopt, there's plenty of tests around this and they don't fail. Is this still happening?

@bsideup
Copy link
Owner

bsideup commented Sep 7, 2021

@raphw yep, consistently. Fails both on CI (see #101) and locally.

% java -version
openjdk version "16.0.1" 2021-04-20
OpenJDK Runtime Environment AdoptOpenJDK-16.0.1+9 (build 16.0.1+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK-16.0.1+9 (build 16.0.1+9, mixed mode, sharing)

@raphw
Copy link

raphw commented Sep 7, 2021

That's strange. Maybe I find some time to check it out. You can run with -Dnet.bytebuddy.dump=/some/folder to see if it emits the same byte code in the mean time.

@bsideup
Copy link
Owner

bsideup commented Sep 22, 2021

Hey @pweso,

I was able to follow @raphw's advice (decorate instead of redefine) with a custom field stub instead of MemberSubstitution, which is trivial and does not fail with AdoptOpenJDK.

I see some great performance improvements locally, could you please give #101 a try and report if it helped with your performance issue? Thanks in advance!

@pweso
Copy link
Author

pweso commented Sep 24, 2021

Hi @bsideup,
I see this repository is set up under Gradle, but I'm using Maven. Could you please tell me how to build this plugin on Maven? Another option is to deploy the new version on the mvn repo.

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

No branches or pull requests

3 participants