There are three key factors to considered when you want to optimize your Java ME applications
You should delay optimization until the last minute, after you create the main features of our application, but you need to keep in mind all the key factors throughout the development cycle to avoid huge changes at the end.
Contents |
Rule number one for performance is "keep it simple", don't try to create over complex systems, for your mobile phone, remember people want fast and easy to use applications/games, to use on the move. With this mind take in account the following issues:
An example for the base structure for you application:
public void startApp() { animationThread = new Thread(this); } public void run() { init(); while(!exitApp) { updateModel(); // your app logic repaint(); serviceRepaint(); sleep(50); // may choke slow devices if too small } }
You must handle with care the system callbacks, they are called by the system thread. They must not block and should return as soon as possible to avoid slowing down the VM. A crash can happen if not returning quick enough. Here is a list with the more common system callbacks:
* paint * keyPressed * startApp/pauseApp * hideNotify/showNotify * MIDlet constructor
Below you have a bad example of a system callback:
public void paint(Graphics g) { updateModel(); drawBackground(g); drawForeground(g); } public void run() { while(!exitApp) { repaint(); serviceRepaints(); sleep(50); } }
As you may have noticed we are updating our model, an expensive operation, during the system event paint. We should change our code to the following:
public void paint(Graphics g) { drawBackground(g); drawForeground(g); } public void run() { while(!exitApp) { updateModel(); // better do it here repaint(); serviceRepaints(); sleep(50); } }
There are huge differences between high end and low end devices, devices can be much faster or slower than you expected, so you cannot assume performance.
If you have your game logic based on frame rate this may result in totally unplayable game. You should instead base your game on actual time instead, like the example below:
public void updateModel() { curTime = System.currentTimeMillis(); elapsedTime = curTime – prevTime; // using elapsedTime for your app logic here prevTime = curTime; } public void run() { while(!exitApp) { updateModel(); repaint(); serviceRepaints(); sleep(50); } }
Another thing to take in account is the performance of some APIs, some calls are slower than others:
Another thing to handle with care is collision detection, it must be calculated in between frames to avoid problems on low frame rate devices.
Disable certain features on slow device via JAD entry. E.g. if "tree.png" does not exist, don't draw the tree sprite
The use of RMS and getResourceAsStream calls is very slow. Take the following consideration when using them:
RMS
getResourceAsStream()
Here some “Little things” that make big differences:
Take a look at the following example:
for(y = 0; y < oriHeight; y++) { for(x = 0; x < oriWidth / 2; x++) { int idx1 = y * oriWidth + x; int idx2 = (y + 1) * oriWidth – 1 - x; curPixel = buf[idx1]; buf[idx1] = buf[idx2]; buf[idx2] = curPixel; } }
If we do the index creation outside of the loops like this:
int idx1; int idx2; for(y = 0; y < oriHeight; y++) { idx1 = y * oriWidth; idx2 = (y + 1) * oriWidth – 1; for(x = 0; x < oriWidth / 2; x++) { curPixel = buf[idx1]; buf[idx1] = buf[idx2]; buf[idx2] = curPixel; idx1++; idx2--; } }
It can save a few seconds on a real device!
The size restriction for Java ME applications comes from two sources:
Device JAR size limit has improved continuously over time, but it is never enough for developers! So here some tips to help you
What does it do? It's original purpose is to make reverse engineering very difficult by:
But is has the nice side effect of creating smaller class files size (and also slightly faster). Some of them also perform bytecode optimization. They can typically can reduce file size by 30–50% There are very good Open source obfuscators (Proguard, Retroguard) and many other commercial products.
What are the problems?
Here are the solutions: