Anyone have some hardcore J2ME optimisation tips?
#2 Moderators - Reputation: 1666
Posted 22 March 2005 - 10:54 AM
Beyond that, I'd have to see some code...
#3 Members - Reputation: 100
Posted 22 March 2005 - 11:06 AM
String a = "";
for (...)
a += "some string" + "other one";
use a StringBuffer:
StringBuffer a = new StringBuffer("");
for (...)
a.append("some string").append("other one");
because the compiler transforme any string manipulation like:
a = b + c;
in this:
a = new StringBuffer(b).append©.toString();
It a lot of useless creation of new object
an you can reset de contain of a StringBuffer... it's probably faster than
create a new one...
P.S. excuse my english
#5 Senior Moderators - Reputation: 1744
Posted 22 March 2005 - 11:21 AM
#6 Members - Reputation: 285
Posted 22 March 2005 - 08:34 PM
Zahlman: how can i get away without using arrays in a simulation where I need vector mathematics? I know i oculd define an int x,y for every vector, but that just gets messy.
#7 Members - Reputation: 186
Posted 23 March 2005 - 12:43 AM
http://www.javaperformancetuning.com/tips/j2me.shtml
http://www.developer.com/java/j2me/print.php/10934_2234631_1
http://www.protomatter.com/nate/java-optimization/
http://www-2.cs.cmu.edu/~jch/
http://www.javaworld.com/jw-04-1997/jw-04-optimize.html
http://www.javaworld.com/javaworld/jw-09-1998/jw-09-speed.html
#8 Members - Reputation: 285
Posted 23 March 2005 - 02:00 AM
http://www.cs.uiowa.edu/~jones/bcd/divide.html
http://aggregate.org/MAGIC/
http://www.dspguru.com/comp.dsp/tricks/index.htm
http://www.azillionmonkeys.com/qed/tech.shtml
http://www.math.purdue.edu/~clomont/Math/Papers/2003/InvSqrt.pdf
http://www.worldserver.com/turk/computergraphics/InverseSqrt.pdf
#11 Members - Reputation: 186
Posted 23 March 2005 - 09:47 PM
Some mobiles are horribly slow.
There was a topic like this here allready, seach for it.
(Zahl and I posted in it as well)
Here are some quick suggestions:
replace for with while loops.
reference fields in local functions.
i.e.
instead of this.m_bigassarray
do int[] bigassarray = this.m_bigassarray
Not only with arrays but with everything.
Every access directly to arrays or classes costs you time.
Also every array dimension you need to access costs ya.
Use ints! The others take less space but using them is more expensive.
Do not create Objects at runtime.
No, avoid them like the pleague!!
You can usually get by with int arrays.
If you REALLY REALLY need them, recycle them!
Create the amound you presume you will need ahead of time and hold them in a sepperate vector, when you want to create one, fetch it out of the backup vector and use it. When you are done put it back in.
o.c. you have the standard optimizations:
save on not needed/redundant calculations
shifting better then division/multiplications
#12 Members - Reputation: 285
Posted 23 March 2005 - 10:42 PM
Quote:
Original post by Frank Henry
Some mobiles are horribly slow.
Tell me about it, but I've no choice. I've got 6-18fps on a 3200 , I'm impressed as it is a slow phone. I need to get average 15fps you see, cause according to the mobile developer grapevine thats what gameloft's development team on Midnight Pool has got, as this is a competing game. I have to get this running acceptably on all S40's as well [bawling]. I haven't seen another Pool game running on S40 at accetable rate, in J2ME at least.
Quote:
Original post by Frank Henry
replace for with while loops.
done.
Quote:
Original post by Frank Henry
reference fields in local functions.
i.e.
instead of this.m_bigassarray
do int[] bigassarray = this.m_bigassarray
Most of the varibles are local already, and I'm not using any classes.
Quote:
Original post by Frank Henry
Also every array dimension you need to access costs ya.
Arghh!!! How much cost? I really don't want to slpit it into 1D arrays, but if I have to I will. Will splitting it into 1D arrays help as I still have to reference 2 int arrays every loop?
#13 Moderators - Reputation: 1666
Posted 24 March 2005 - 11:25 AM
Quote:
Original post by pkelly83 Quote:
Original post by Frank Henry
Also every array dimension you need to access costs ya.
Arghh!!! How much cost? I really don't want to slpit it into 1D arrays, but if I have to I will. Will splitting it into 1D arrays help as I still have to reference 2 int arrays every loop?
If your array is rectangular, don't split it - join it. And calculate the indices manually. (Possibly this may involve caching index values and adding some offsets...) int[][] is overly flexible; it doesn't enforce rectangularity, so if you don't need that freedom, you're paying unneeded overhead.
#14 Members - Reputation: 1277
Posted 24 March 2005 - 12:00 PM
What you would be profiling would be the desktop J2ME implementation which is likely to be running a totally different JVM and libraries from the actualy phone.
Many "Emulators" (I use the word looseley here) actually don't emulate the device at all, rather they just simulate the vendor-specific libraries - and do so in a fashion which bears absolutely no resemblance, performance-wise, to the device itself.
I've no idea how accurate the timers are on these devices so you can try to roll your own on-device profiling, but I suspect not very accurate.
Anyway I pretty much suss it out by observing the behaviour of the game with different numbers of different objects on the screen.
I've found that the graphics library is so incredibly slow, that even if my code were horribly inefficient, it would still make little difference.
Of course this depends what sort of game it is, you might have to do some intense stuff.
But in any case, you should focus on better algorithms, not micro-optimising code which you're not sure whether it's important because you can't profile it correctly.
Mark
#15 Members - Reputation: 285
Posted 24 March 2005 - 11:08 PM
Quote:
Original post by markr
I've found that the graphics library is so incredibly slow, that even if my code were horribly inefficient, it would still make little difference.
Yep thats the main problem right now acoording to both WTK's profiler and timing on the phone itself. 50% of my frame time is taken by graphics drawing.
#16 Moderators - Reputation: 1666
Posted 25 March 2005 - 10:18 AM
Also, compare the drawing speeds of various primitives and images (for images, compare clipped and non-clipped), and make use of this information.
#17 Members - Reputation: 834
Posted 25 March 2005 - 11:43 AM
There are two main ways to speed up drawing:
The first is "dirty-recting". You keep track of which screen elements are "dirty" (in need of redrawing), and you only redraw those elements. This one only works if there is a lot of stuff that stays still. It doesn't really work if the whole screen changes every frame, like say Super Mario Bros or something.
There are different ways to do dirty-recting. My favorite method is to keep track of the dirtyness in terms of rectangles. Every time something happens that makes something on the screen dirty (like say, the score changes, or the main character steps on a landmine and begins an explosion animation), you calculate the rectangle that encompasses this element, and you add it to a dirty rectangle list.
Then, when you redraw the screen, you first go through your dirty rectangles and "coalesce" them. That is, you check each rectangle against the others to see if it overlaps a lot, and if they overlap, you combine the two into one big rectangle. The strategy I actually used was that if two rectangles intersected *at all*, I would combine them. And in some games, it worked well to just always combine every rectangle into one big one. The needs of your game may vary.
Once you have your list of remaining rectangles, you loop through each rectangle, set the cliprect to that rectangle, and then call your draw function as normal. See, the nice thing about this method is that you don't have to change your draw function at all, the optimization comes from using cliprects. The theory here is that when the drawing code results in a draw call to a part of the screen that's clipped out, that code will be executed in a trivial amount of time.
Personally I don't really trust a Java Image to actually do nothing when I try to draw it somewhere where it is completely clipped out, so I recommend having your own Image wrapper class (if you don't already), which, when you draw it, checks itself against the current cliprect and returns immediately if it is clipped out.
You might balk at adding all that extra processing, and be worried that all that extra work will slow you down. But trust me, that processing is totally worth it if you can reduce the amount of drawing you do. Draw calls are an enormous, huge, un-small time sink.
The other good way to speed up drawing is to cache things onto an offscreen buffer. I almost never used this method for the games I worked on, because we pretty much always had the phone's runtime memory completely stuffed with art assets, and we couldn't spare the extra memory. This might not be a problem for your game.
#18 Members - Reputation: 285
Posted 25 March 2005 - 11:40 PM
Quote:
Original post by pinacolada
The first is "dirty-recting".
That is a good idea, I even used this before on home made PC games I wrote. I just never really thought about using it on the phone. Guess I can use that joined arrays trick to store the rectangles in a 1D array. Thanks for that idea, that is thinking outside the box. You could even compress it into one int using right shifts as the screen is only 128x128 on an S40, and that will work on S60 too. Sweet.
Quote:
Original post by pinacolada
This might not be a problem for your game.
Believe me, memory is a big problem. We are using a buffer already and it's still slow.
#19 Members - Reputation: 169
Posted 26 March 2005 - 06:58 AM
Then draw this complete image to the screen in one draw to the 'actual' screen.
Is it faster drawing to the (buffer)image say 10 times and then only drawing 1 large image to the phones screen?
About dirty-recting is that just setting clip regions so the when the buffer image is drawn to the screen only the smallest amount of pixels on the screen need updating are updated?
So from that i take it thats its the actual drawing the the screen thats slow and not all the 'draw' methods themselves that are slow.
#20 Members - Reputation: 834
Posted 27 March 2005 - 02:53 AM
So having an offscreen buffer is good, because when you draw it to the screen, you have reduced the number of draw operations to just one. But you still don't want to redraw the entire screen if you can help it, because this involves repainting a large amount of area, which will also be slow.
I myself don't know how much faster offscreen buffers are, since I didn't use them much. It might even be possible that drawing to an offscreen buffer isn't faster than drawing to a screen at all.
But one thing that's definitely faster is to "cache" the drawing. Say you have some element that requires several draw calls (like maybe the game background), but doesn't change during the game. You draw this element to an offscreen buffer once, then once you have the completed image in the buffer, you can draw it to the screen and it will only cost you 1 image draw per frame. This method can even work on screen elements that *do* change, but they change infrequently. Every time the screen element changes, you have to take the performance hit of redrawing the offscreen buffer- but you'll still have a performance improvement for most of the time.
So here is the executive summary:
Quote:
Original post by Woody FX
Is it faster drawing to the (buffer)image say 10 times and then only drawing 1 large image to the phones screen?
Don't know
Quote:
About dirty-recting is that just setting clip regions so the when the buffer image is drawn to the screen only the smallest amount of pixels on the screen need updating are updated?
Yes
Quote:
So from that i take it thats its the actual drawing the the screen thats slow and not all the 'draw' methods themselves that are slow.
They are both slow.






