-
Notifications
You must be signed in to change notification settings - Fork 227
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
Optimize generated code to reduce method count. #81
Comments
There's a TODO for skipping package scoped accessor methods in the code base already: https://github.com/orfjackal/retrolambda/blob/6371ddaa52262d3e42262ad0a409bf0d435eeb10/retrolambda/src/main/java/net/orfjackal/retrolambda/lambdas/BackportLambdaInvocations.java#L65 |
There is quite much work in implementing those optimizations, because bytecode manipulation is hard, so I hope that somebody else would have the time to look into it and create a pull request. |
RE 2: I don't mean changing the user code at all, but the private static method which is generated (
It is hard, but I'm not opposed here having done my share of ASM. I filed the issue to get initial thoughts, and I'm definitely going to try one or two next week. Would too love to see some additional help. |
@orfjackal Can you explain your response to 4 more? I don't quite understand where that |
I have implemented 3, but would like #82 to be merged first since I want to use its added tests to prove the factory method is no longer included. Doing so as a sibling PR would only cause merge conflicts. |
RE 2: Some of the generated RE 4: the |
Your pull requests are now included in Retrolambda 2.3.0. Sorry for taking so long. 😓 |
Thank you! |
Android's file format, dex, is highly sensitive to the number of methods in the contained class files. There's a method table with a 16-bit index which thus restricts the number of methods to 65536. "65536 methods?" you might say, "that should be enough for anyone!" Unfortunately these add up quick for all kinds of reasons.
As I'm sure you are aware, Retrolambda has a big userbase in the Android community due to the restriction of the toolchain only understanding Java 6/7 classfiles. Minimizing the number of methods generated per lambda and method reference would go a long way to help keep applications under this limit.
There's currently four cases whose generated code can be altered to reduce the number of required methods required for each lambda and method reference. By my estimation this will remove between 2000 and 2500 method references from our app! For our current usage count, that's approximately 5%!
Instance factory method
All
$$Lambda$
classes have alambdaFactory$
method which either returns a new instance for capturing lambdas or a cached instance for non-capturing lambdas. The implementation either delegates to theprivate
constructor or aprivate static
field. Removing theprivate
modifier and making these package scoped would allow the constructor or field to be reference directly from the original call site avoiding the need for this method altogether.Non-capturing example:
Generates:
Capturing example:
Completed Parts 🎉
Non-private method references(#84)Method references on non-private methods (both static and instance) generate a needless package-scoped accessor method. This only needs generated for private methods. All other versions can effectively "inline" the method call directly to the generated
$$Lambda$
class.Example:
Generates:
Lambda body methods(#86)The body of a lambda is copied into a
private static
method on the defining class with any captured references hoisted into parameters. Being aprivate
method, though, an additional accessor method has to be created so that the$$Lambda$
class can call back into it. Promoting the lambda body method itself to package scoped eliminates the need for this extra indirection.Example:
Generates:
Unused factory method(#82)A factory method named
get$Lambda
shows up on the$$Lamda$
classes for capturing lambdas. This method duplicates the implementation of thelambdaFactory$
on the same class but is completely unused.The text was updated successfully, but these errors were encountered: