proguard icon indicating copy to clipboard operation
proguard copied to clipboard

Lambda inlining optimization

Open TimothyGeerkensGuardsquare opened this issue 1 year ago • 5 comments

Added lambda inlining for Kotlin lambdas passed directly as an argument or stored in a variable then passed as an argument. It currently cannot inline lambdas that are passed to a method and then used as an argument to a method called from the first method. We currently do not inline from final fields, nor from lambdas returned from methods. So we just handle the most basic cases for now.

  • [x] Retrace
  • [x] Only inline lambdas based on certain rules
  • [x] Start to end example with multiple steps in bytecode
  • [x] Replace aconst_null with getstatic call to the lambda class
  • [x] Add enable/disable option for the lambda inlining

Can you provide some timings for a few applications: how big the applications are and how much time this inlining pass takes?

rubenpieters avatar Aug 04 '23 09:08 rubenpieters

So currently the only real world application we tested it on is the klox compiler, it contains many lambda usages so it seemed like a good test. By just inlining the more basic lambdas we are currently focusing on we were able to get a ~10% performance increase. So this is without running proguard on it so only lambda inlining. Inlining the lambdas took around 30s.

Benchmark 1: java -jar result.jar wc.lox -o Test.jar
  Time (mean ± σ):      1.831 s ±  0.107 s    [User: 6.152 s, System: 0.238 s]
  Range (min … max):    1.717 s …  2.025 s    10 runs
 
Benchmark 1: java -jar test-files/klox.jar wc.lox -o Test2.jar
  Time (mean ± σ):      2.012 s ±  0.173 s    [User: 6.715 s, System: 0.238 s]
  Range (min … max):    1.822 s …  2.345 s    10 runs

We will try do run it on some more real world applications including android apps.

MaartenS11 avatar Aug 04 '23 09:08 MaartenS11

Can you provide some timings for a few applications: how big the applications are and how much time this inlining pass takes?

Current performance on a few android applications :

ANOTHERpass :

  • Inlining pass runtime = 4078ms
  • Number of lambdas found = 24
  • APK size before proguard = 5.3MB
  • APK size after proguard = 3.2MB

OneList :

  • Inlining pass runtime = 4651ms
  • Number of lambdas found = 31
  • APK size before proguard = 5.2MB
  • APK size after proguard = 3.0MB

Antimine :

  • Inlining pass runtime = 47651ms
  • Number of lambdas found = 158
  • APK size before proguard = 10.1MB
  • APK size after proguard = 5.0MB

We noticed that proguard-core and proguard both have a version of the LambdaExpressionCollector, I guess it was moved over into proguard-core at some point but never removed here? They are also in the same package which can cause Intelij to understandably get a little confused sometimes.

MaartenS11 avatar Aug 11 '23 12:08 MaartenS11

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

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

No Coverage information No Coverage information
0.0% 0.0% Duplication

sonarqubecloud[bot] avatar Aug 13 '23 11:08 sonarqubecloud[bot]