Posted by & filed under Dissertation.

Over the holidays I have learnt quite a bit about optimising performance when using Libgdx on Android. I felt like it was a good subject to write a blog post about as it might be helpful to others who are starting out with Android development. Further to this it may well end up being a section in my final report.

SpriteCache

One such way to optimise performance in Libgdx is to use the SpriteCache class. This class draws 2D images like SpriteBatch; however this class is more optimised for images where their geometry doesn’t change. The class caches any sprites/textures with a given ID which it then uses later to draw the image. Once the image has been cached its size, colour and texture region cannot be modified. This is a bit like the ‘final’ modifier in Java.

The way the optimisation works is that it stores the cached information in video memory, this means that it does not have to be sent to the GPU each time it’s drawn like it does with SpriteBatch. When designing games for Android devices you want to limit the calls to the GPU as much as possible, in an ideal world you’ll want to only have one call per frame update, however as your game grows this becomes more and more unlikely. Utilising SpriteCache to draw all your objects that won’t be doing anything other than sitting there is good practice.

Java Lists

Stay away from these. Java lists create a lot of unwanted garbage which your device will have to deal with. This means that your device will have to put aside some of its resources to clean up after the lists. ArrayLists are a little better but they still create some unwanted garbage. If an unordered list is what you want then you’ll want to implement the Libgdx Array class. This class has some nifty optimisations like not performing a memory copy when removing elements; instead it moves the last element to the removed elements position.

While the Array class is pretty cool, it still isn’t the most optimised. If you can you will want to initialise an array with a fixed size, like most things in programming a fixed size array will get you the best performance.

Loops

When performing any loops in your program you should be aware not to create any new operators. This also means that you should be aware of any classes that Libgdx (or Java) has that generate new objects.

When it comes to for loops you have three different options to choose from.

  1. for (int x = 0; x < myArray.length) {}
  2. for (int x = 0; x < length; x++) {}
  3. for (Foo x: myArray) {}

The first loop is the slowest as the compiler has to get the size of the array for every iteration of the loop.  The second loop uses a local variable called ‘length’ and this does offer a slight performance increase but not much. The third loop is the fastest type of loop as it uses the enhanced for loop syntax first implemented in version 1.5 of Java.

Prefer Static Over Virtual

If accessing an object’s isn’t something you need to do, then make your method static. Invocations will be around 15%-20% faster. This is also helps you understand from the method signature whether or not the method can or cannot alter the object’s state.

Use Static Final For Constants

If you have a variable without the final constant, when the compiler generators a class initializers called <clinit>. This method stores the value of your variables into whatever you have named them. Then when you access these variables later on they are accessed with field lookups.

Using the ‘final’ keyword helps improve this as the class now no longer requires the <clinit> method because the constants go into a static field initializers in the dex file. When you refer to your variables they will now be referred to directly rather than using field lookups.

Avoid Internal Getters/Setters

This was something that came as a surprise to me as I have always been encouraged to use these at university.

In native languages like C++ it is common practice to use these types of methods because the compiler can inline the access and it allows you to restrict access to certain variables from the rest of your code.

On Android this is a bad idea. Virtual method calls are more expensive that instance field lookups. It makes sense in my head to follow the common object-orientated programming practices but you should get out of this habit when programming in Android and start accessing fields directly.

If you are not using a Just-In-Time compiler then accessing fields directly is about three times faster than using a getter. If you are using a Just-In-Time compiler then direct access is seven times faster.

Floating-Point

Floating-point is roughly twice as slow as integers on Android devices. If you can you will want to use integers instead of floating point variables.

If you find yourself needing to use something heavier than an integer, you may find yourself looking at floats and doubles. There isn’t much difference between the two apart from doubles are twice as large as floats. In terms of speed there is no difference, therefore if space is not an issue you’ll want to use doubles.

Summary

There we have it, a quick summary into what I have found about optimising the performance of your code when writing for Android.

I would like to point out that this is not a definitive list; it is merely what I have discovered in the Christmas period. If you disagree with something I have said then I encourage you to comment below and say why, I’m always interested in learning more about code optimisation. Also, if you feel that you have a neat trick to share then please comment with that.

Sources: Libgdx Forum Post & Android Performance Tips

Leave a Reply

You must be logged in to post a comment.