-
Notifications
You must be signed in to change notification settings - Fork 67
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
Avoid unnecessary linked list traversals in MethodLinker. #133
Avoid unnecessary linked list traversals in MethodLinker. #133
Conversation
The chains themselves are assumed to be an implementation detail of this class, in which case it's fine to flatten them at any time.
Hey @LlamaLad7 ! Thanks for the PR, your approach looks like a nice improvement. We will be looking at the suggestion further, but we will need to do some additional testing first to ensure the change is safe to apply also in our internal projects using ProGuardCore. |
@rubenpieters Unfortunately the project is proprietary, so I can't share it. We are using obfuscation, hence the work in I've made a slightly contrived example here (https://github.com/LlamaLad7/slow-proguard-example) with a lot of methods in a large inheritance chain. MethodLinker spends about 15 seconds traversing the chains without my change, and about 1 second with my change. Hopefully this helps. |
@LlamaLad7 The reproducing project you shared is indeed helpful in reproducing the effects you describe, so thanks for that! We are planning on having a further look on the impact of this in our internal projects, as we haven't gotten to it yet. Mainly to ensure we don't introduce any unexpected side effects as mentioned before. |
Hi @rubenpieters! Colleague of @LlamaLad7 here; I just wanted to check in on this PR. We're anxious to get it merged as it'd result in a pretty significant speed up of our CI runs. We're considering compiling our own build of ProGuard and using that, but if this PR is close to being approved, we'd be happy to wait it out. |
Hey @colinmcdonald22 , we will still need a bit more time to properly review this. We have reviewed our internal usages of the MethodLinker, and that looks fine with your change as well. So we will be able to merge the PR soon (likely by the end of the week). But before it makes it into a release, e.g. ProGuard we would like to make sure it has no adverse effects on our own internal CI tests. I would expect ~2 ish weeks before we can make a release with this change in it. Does that provide enough information regarding the timeline for you? |
Yes that’s very helpful, thank you! |
The chains of method links can get surprisingly large and a huge amount of time can be wasted repeatedly traversing them.
![image](https://private-user-images.githubusercontent.com/15244077/400096236-9fb497be-b05d-4567-aac7-cc270cee8d75.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5MjkwNDAsIm5iZiI6MTczOTkyODc0MCwicGF0aCI6Ii8xNTI0NDA3Ny80MDAwOTYyMzYtOWZiNDk3YmUtYjA1ZC00NTY3LWFhYzctY2MyNzBjZWU4ZDc1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE5VDAxMzIyMFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTJkYWYxZDMzYmM5ZTM1MzYzZjA0MDRiMTc3NDExNmZmOTZhYjQyMDExMzg5OTY3ZjFjMzQ1YzgzYmM4NDI5NWQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.hFakjli6LpezJmdRSS4aJnX0qqF6OS4UftOD5Q1hsCI)
![image](https://private-user-images.githubusercontent.com/15244077/400096166-46db76a5-9fd5-4a9e-a2d4-e3a0079ce6ed.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk5MjkwNDAsIm5iZiI6MTczOTkyODc0MCwicGF0aCI6Ii8xNTI0NDA3Ny80MDAwOTYxNjYtNDZkYjc2YTUtOWZkNS00YTllLWEyZDQtZTNhMDA3OWNlNmVkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE5VDAxMzIyMFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTI2MTVlM2ZmNzE2YTU3OWYyZGIwYzE0MzkwMmJmYjg5ZDQxNTU5NDE5M2JmNmFmOTQ2ODVmOGZlMmIxNTQ0Y2YmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.k802r6CoRnyYPMZ2YvL3KKPgHZvxpbX1DMC_1LvWJng)
We can cut down most of this time by flattening the chain each time we traverse it, pointing every element straight to the end.
The chains themselves are assumed to be an implementation detail of this class, in which case it's fine to flatten them at any time.
Some profiling from building one of my projects with ProGuard:
Before:
After:
I'd imagine that there are ways to avoid linked lists at all in this linking process, but this change is minimally invasive to the external API and the speedup is very large.