Removing unused strings during ProGuard optimisation

ProGuard can remove simple constant arguments (Strings, integers, etc). So in this case, the code and the string constant should disappear completely:

Log.d("This is a debug statement");

However, you may have observed the issue with some code like this:

Log.d("The answer is "+answer);

After compilation, this actually corresponds to:

Log.d(new StringBuilder().append("The answer is ").append(answer).toString());

ProGuard version 4.6 can simplify this to something like:

new StringBuilder().append("The answer is ").append(answer).toString();

So the logging is gone, but the optimization step still leaves some fluff behind. It’s surprisingly tricky to simplify this without some deeper knowledge about the StringBuilder class. As far as ProGuard is concerned, it could say:

new DatabaseBuilder().setup("MyDatabase").initialize(table).close();

For a human, the StringBuilder code can obviously be removed, but the DatabaseBuilder code probably can’t. ProGuard requires escape analysis and a few other techniques, which aren’t in this version yet.

As for a solution: you can create additional debug methods that take simple arguments, and let ProGuard remove those:

MyLog.d("The answer is ", answer);

Alternatively, you can try prefixing every debug statement with a condition that ProGuard can later evaluate as false. This option may be a bit more convoluted, requiring some additional -assumenosideeffects option on an initialization method for the debug flag.

Leave a Comment