From the beginning I designed Pury in the way that it could evolve into a system with a single core and multiple plugins and extensions. So that people could customise it in the most suitable way. And as a first step into that direction I would like to present you Plugins.

Custom Plugins

In the previous version it was possible to change a Logger to take advantage of libraries like Timber. Plugins allow much more flexible customisation. They provide access to raw results to process them in the most suitable way. For example, it could be interesting to compare performance between master and feature branch, I have a few ideas how to do that, but didn’t tried them yet. Or change formatting to a JSON, run application in a device farm, collect results and compare them with some script. I always wanted to measure application performance on live. So I played a bit with Google Analytics and got promising results. Instead of getting standard Pury output:

App Start --> 0ms

Splash Screen --> 5ms

Splash Load Data --> 37ms

Splash Load Data <-- 1042ms, execution = 1005ms

Splash Screen <-- 1042ms, execution = 1037ms

Main Activity Launch --> 1043ms

onCreate() --> 1077ms

onCreate() <-- 1100ms, execution = 23ms

onStart() --> 1101ms

onStart() <-- 1131ms, execution = 30ms

Main Activity Launch <-- 1182ms, execution = 139ms

App Start <-- 1182ms

I sent execution times to Google Analytics Timing API and got this:

As you can see I got all execution times in a single table. Taking into account GA Segments, it could be a very powerful tool to analyse application performance across different versions and devices. I’m planing to write an article about Google Analytics Timing API and Google Analytics Plugin once it is released, but in the meantime I would like to go back to Pury Plugins in general.

Plugin creation

To create a custom plugin you need to implement Plugin interface:

public interface Plugin {

void handleResult(ProfileResult result, ProfilerId profilerId);

}

In handleResult() Plugin receives a result of profiling and an identifier of the profiler which produced the result. It worth to mention that ProfileResult is an interface with 4 different implementations. To simplify result processing I made a use of Visitor Pattern, each result has a method accept(ResultVisitor). And this is ResultVisitor interface:

public interface ResultVisitor {

void visit(AverageProfileResult averageProfileResult);



void visit(RootAverageProfileResult rootAverageProfileResult);



void visit(RootSingleProfileResult rootSingleProfileResult);



void visit(SingleProfileResult singleProfileResult);

}

There is a method for each of the result type, so no checks or casts are required. I hope you will find it useful.

While I was writing support for Plugins, I thought that filtering input by profiler name could be a very common use case. So if you think that an abstract class that implements Plugin and does filtering is useful, please raise an issue on GitHub.

How to use Plugins

To add and remove plugins on the fly use the following methods:

public final class Pury { .... public static void addPlugin(String key, Plugin plugin) {}



public static void removePlugin(String key) {} .... }

There is a Map behind those two methods, so if two plugins with the same key are added, the first one is removed.

Logging Plugin

With introduction of Plugins, I decided to change the way logging works. So now logging is just an another Plugin, nothing more. To take a look into the code, please, check LoggerPlugin class.

LoggerPlugin is added by default, so logging is working out of the box. To remove or replace it, use the key Pury.LOGGER_PLUGIN. LoggerPlugin uses the same Logger, as was used for logging results before. To change it use Pury.setLogger(Logger) method.

Conclusion

Plugins enable customisation and better control over reporting profiling results. They adds a certain degree of flexibility to Pury that, I hope, will be useful. You can find code with example on GitHub.

As I’ve already mention, right now I’m working on integration Pury with Google Analytics. If you are interested in results then follow me on Twitter or here, on Medium. If you have ideas about what else can be done with profiling results, please write in comments or in Gitter.