I wanted to start a thread about how to minimize size of midlets. At work we’ve hit the 64KB limit of OTA, and MIDP 1.1 specification. We knew we were going to hit it, and so we made a lot of “optimizations” to ensure we won’t have any size issues.
Most of the work thus far (bar some image optimization techniques) has been “uglyfication”, by which I mean: inline stuff, increase visibility of fields and so forth. Though we are well below the 64 KB limit again (wohoo) I would like to make it even smaller.
How did you you guys solve these issues? - What optimizations saved you most bytes?
It should be said, that content needs to be packaged in the midlet suite, and that the midlet is already being obfuscated.
One of the biggest gains, was by grouping images together, and then having an array that contained regions on the main picture to paint from. This saved us a lot of Image refernces, but most importantly we shaved several PNG headers of the image files.
It’s funny that doing j2me is actually somewhat counter java intuitive, in that one has to limit classes and abstraction to almost non existant, sort of like coding to the metal in the good old days
another simple byte shaver (though it will hit performance) is to use if/else instead of switch statements.
The problem with switch is hat it builds a lookup table, which wastes much more bytes than an if/else construct. Ofcourse this is also slower.
I’ve seen anything from 10-300 bytes savings on doing this - ofcourse dependent on the size of the switch statement.
btw, one thing that really annoys me, is that we have to use a zip compresion for jar files. If the RAR format (though it won’t be, since it is proprietary) was supported we’d have 1/3 better compression!
I particularly like the way that the Pre-verifier adds (at least for me) 15%-22% size increase to the class files!!
Have a go at compiling your classes manually then look at the class file size before and after Preverify and note how much bigger they get…
Does anybody actually know what the Preverifier actually does? Its only supposed to add a stack map attribute to each method but I’ve come across classes it does not seem to touch.
Thats another way to squeeze those class files, use as few methods as possible!
The MIDP V1.0 spec states that for memory consumption the minimum should be:
128K of non-volatile memory for the MIDP components.
8K of non-volatile memory for application-created persistence data
32K of volatile memory for java runtime (heap etc).
All these other limitations (such as max class file size, or jar file size) are just imposed by the manufacturer.
For example almost all (if not all) current (2003) Siemens phones have a wonderful size constraints of 16K on everything:
it adds stack map only to those class that use branch bytecode operation. if you use try-catch, if-then-else and switch-case, your classes will add a lot of size because of the stack map. avoid those.
(note: i am not 100% sure which statement translate to branch operation, correct me if i am wrong. it is just my observation)
no1 has mentioned the 2nd biggest saving (after obfuscation)
Use a proprietary image format specific to the device you intend to deploy on,
Compression isn’t necessary, the jar will compress it pretty well anyhow (though having a simple RLE algorithm may save u a little bit more)
Then, pack them into a single file, images.dat or something. (less files in a jar, the smaller the jars index table)
To read the images in, you will need to use manufacturer specific calls, but both the Siemens and Nokia extensions provide the necessary methods.
Doing this will both accelerate load times, and decrease app. size.
Currently, we use WinRar to shave off ~1 kB, and this works fine. As long as it’s the std zip compression rutine you’re fine. I’ll have a look at 7zip…
Those scores for the T-610 look extreme fishy, they are all over the place. A genuine score seems to be ~279, yet there are scores up to 402 and as low as 175. But the dates are intermixed, so a recent score does not mean a higher score (so would not suggest a firmware update).
This seems a bit funny for a device which has not been changed (as in a faster CPU for new versions) or (to my knowledge) a faster KVM + libraries.
The T-610 is not a fast beast when it comes to J2ME, it used to be 3rd from bottom on your list at one point. Which is rather disappointing as the phone is quite good.
Of course it could be just down to the benchmark being interrupted, or even an inaccurate system clock.
A system clock accuracy test would be a good one to add to JBenchmark, at least it would be informative (would also force phone Manufacturers to at least try and make them accurate, because it would look bad if they didn’t).
You also don’t impose a penalty for failing a test, the T-610 cannot generate an image larger than its screen size and so fails the animation test.
Got to ask, whilst I’m at it, whats ATi’s connection with your JBenchmark 2 are they about to launch a mobile gfx chip? Your NDA is safe with us, we can keep a secret! Honest