Pages

Showing posts with label compilation time. Show all posts
Showing posts with label compilation time. Show all posts

Saturday, March 3, 2012

Proguard performance and Scala versions

We have been holding back from moving to Scala 2.9 for a long time now. The reason is that Scala builds for Android need to be treated with Proguard to reduce their size. And on Scala 2.9, Proguard is incredibly slow. I think this has to do with the trait bloat that was creeping up on Scala library while it gained more and more features. Now that it's "fixed" by introducing more abstract classes to Scala 2.10 I was interested in seeing if my guess was correct and if the proguard performance would back to 2.8 level.

After fixing some issues in our build introduced by Scala 2.10, I run our build for Scala versions 2.8.2, 2.9.1 and 2.10.0-M2 (the currently latest milestone release). Timing information was gained from Lasse Koskela's maven-build-utils which I've done some work with lately.
Our build includes 7346 lines of Scala and some Java. Here's the performance information:

Scala 2.8.2

[INFO]   compile                                  32.6s  45%
[INFO]     maven-compiler-plugin:compile           3.0s   9%
[INFO]     maven-scala-plugin:compile             29.6s  90%
[INFO]   process-classes                          18.7s  26%
[INFO]     android-maven-plugin:unpack             0.7s   3%
[INFO]     proguard-maven-plugin:proguard         18.0s  96%

Scala 2.9.1

[INFO]   compile                                  32.0s  19%
[INFO]     maven-compiler-plugin:compile           3.0s   9%
[INFO]     maven-scala-plugin:compile             29.0s  90%
[INFO]   process-classes                         110.3s  67%
[INFO]     android-maven-plugin:unpack             0.8s   0%
[INFO]     proguard-maven-plugin:proguard        109.5s  99%

2.10.0-M2

[INFO]   compile                                  32.8s  41%
[INFO]     maven-compiler-plugin:compile           3.0s   9%
[INFO]     maven-scala-plugin:compile             29.9s  90%
[INFO]   process-classes                          24.0s  30%
[INFO]     android-maven-plugin:unpack             0.8s   3%
[INFO]     proguard-maven-plugin:proguard         23.2s  96%

As you can see, Proguard takes over 6 times as long on 2.9.1 that it does on 2.8.2. And on 2.10.0-M2 it's almost back to what it was on 2.8.2. So that's really good news for Android developers using Scala. Compile time differences between different Scala library versions are negligible.


Thursday, January 5, 2012

Shrinked Scala jar from proguarded files

Ok short post how to shorten package time when using Scala.

So after you've run your packaging with proguard you should have your scala files under:
target/android-classes

so what you want to do is run the following:
jar cvf shrinked-scala-1.0.jar scala

This will create a file called shrinked-scala-1.0.jar which contains all the Scala files and methods you've used in your project so far.

Next we'll add the file to our local maven repository:
mvn install:install-file -Dfile=./shrinked-scala-1.0.jar -DgroupId=com.punchwolf.scala -DartifactId=shrinked-scala -Dversion=1.0 -Dpackaging=jar

Now that we have the package in your repository we can create a new profile that uses the original Scala for compilation only but takes the shrinked version in to the package as a dependency.


<profile>
<id>hacked</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<use.lazy.unpack>true</use.lazy.unpack>
<compile.scope>compile</compile.scope>
</properties>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.punchwolf.scala</groupId>
<artifactId>shrinked-scala</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
</plugins>
</build>
</profile>
The above profile uses the original scala-lang as provided scope (used in compilation) and the shrinked is used in compilation scope (is packaged in the APK).

what you'll also need to do is to have a default profile that uses proguard and the scala-lang in compilation scope.

now that you have these separated, you can run the following:
mvn clean package -P hacked

Now the compilation should be done without the proguard and your new package should be executable in your phone.

The drawback is that if you use a new Scala feature that you don't have in your shrinked-scala, the program will fail saying that there's no class found. So you'll need to run the proguard profile package again and generate the shrinked-scala.jar from the proguarded scala files.

This is not very useful in the early stage of development, but it's very useful when you have pretty stable set of Scala features you use in your project or if you are debugging something.