More Related Content
Similar to Mgd08 lab01 (20)
More from Hock Leng PUAH (20)
Mgd08 lab01
- 1. !¨ $# © ¤¢#¨©¨!! © ¥§
y–ƒj˜”m iƒ™ l ƒ“k
y–ƒj˜”f iƒw € ƒy€ƒ”h g fƒy†
uuu exw€ƒdyƒ™ ˜y ”€“—“x x“ ƒ–€•”ƒyw“ xy“’ ‘‰ ˆ‡† €…€„ ƒ‚y €yxwv uuu
tspicrpqpihg feY dcba`YXWV
visual result of the optimization process.
Java ME applications. We will also use Java SDK 3.0 together with its profiler tool to get a
This lab will show how, when and why to optimize our code to improve the performance of our
'R(UTRSR(QP
AGIHGFF!©©#¥¤$£D§!¥¨FE!§4§E!¨ $#D¥© ¤¥4¥#222!! © ¥$¥D¥C¥B
£§£¨£© A7 ¢§@9876¦¡ o
¥¨§ 5¡ §4§3 ¥£¨£© 2 1 •
0(')('%
£§£¨£© ¥¨§¦ ¥¤£¢ ¡
- 2. £§£¨£© ¥¨§¦ ¥¤£¢ ¡
w˜“y€ “—“yfE gƒ—€™ y–ƒj˜”m
lƒ¡€¦–€f y¥€•ƒ£¤ ƒ‚y ˜yw“ xƒ“• xx€h €…€„ £w€ yƒ£“¢ wƒ…“¡ ˜iy ƒ‚y @f˜h gF fƒy†
The Midlet: OptimizeMe.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class OptimizeMe extends MIDlet implements CommandListener {
private static final boolean debug = false;
private Display display;
private MyCanvas myCanvas;
private Form form;
private StringItem timeItem = new StringItem(Time: , Unknown);
private StringItem resultItem = new StringItem(Result: , No results);
private Command cmdStart = new Command(Start, Command.SCREEN, 1);
private Command cmdExit = new Command(Exit, Command.EXIT, 2);
public boolean running = true;
public OptimizeMe() {
display = Display.getDisplay(this);
form = new Form(Optimize);
form.append(timeItem);
form.append(resultItem);
form.addCommand(cmdStart);
form.addCommand(cmdExit);
form.setCommandListener(this);
myCanvas = new MyCanvas(this);
}
public void startApp() throws MIDletStateChangeException {
running = true;
display.setCurrent(form);
}
public void pauseApp() {
running = false;
}
public void exitCanvas(int status) {
debug(exitCanvas - status = + status);
¥§F !¨ $# © ¤¢#¨©¨!! ©
- 3. £§£¨£© ¥¨§¦ ¥¤£¢ ¡
switch (status) {
case MyCanvas.USER_EXIT:
timeItem.setText(Aborted);
resultItem.setText(Unknown);
break;
case MyCanvas.EXIT_DONE:
timeItem.setText(myCanvas.elapsed + ms);
resultItem.setText(String.valueOf(myCanvas.result));
break;
}
display.setCurrent(form);
}
public void destroyApp(boolean unconditional) throws MIDletStateChangeException {
myCanvas = null;
display.setCurrent(null);
display = null;
}
public void commandAction(Command c, Displayable d) {
if (c == cmdExit) {
myCanvas = null;
display.setCurrent(null);
display = null;
notifyDestroyed();
} else {
running = true;
display.setCurrent(myCanvas);
myCanvas.start();
}
}
public static final void debug(String s) {
if (debug) {
System.out.println(s);
}
}
}
The Game Canvas class: MyCanvas.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.Random;
public class MyCanvas extends Canvas implements Runnable {
public static final int USER_EXIT = 1;
public static final int EXIT_DONE = 2;
public static final int LOOP_COUNT = 100;
public static final int DRAW_COUNT = 16;
public static final int NUMBER_COUNT = 64;
public static final int DIVISOR_COUNT = 8;
public static final int WAIT_TIME = 50;
public static final int COLOR_BG = 0x00FFFFFF;
public static final int COLOR_FG = 0x00000000;
public long elapsed = 0l;
public int exitStatus;
public int result;
private Thread animationThread;
private OptimizeMe midlet;
private boolean finished;
private long started;
private long frameStarted;
private long frameTime;
private int[] numbers;
private int loopCounter;
private Random random = new Random(System.currentTimeMillis());
public MyCanvas(OptimizeMe _o) {
midlet = _o;
numbers = new int[NUMBER_COUNT];
for (int i = 0; i numbers.length; i++) {
numbers[i] = i + 1;
}
}
public synchronized void start() {
started = frameStarted = System.currentTimeMillis();
loopCounter = result = 0;
finished = false;
¥§‰ !¨ $# © ¤¢#¨©¨!! ©
- 4. £§£¨£© ¥¨§¦ ¥¤£¢ ¡
exitStatus = EXIT_DONE;
animationThread = new Thread(this);
animationThread.start();
}
public void run() {
Thread currentThread = Thread.currentThread();
try {
while (animationThread == currentThread midlet.running !finished) {
frameTime = System.currentTimeMillis() - frameStarted;
frameStarted = System.currentTimeMillis();
result += work(numbers);
repaint();
synchronized (this) {
wait(WAIT_TIME);
}
loopCounter++;
finished = (loopCounter LOOP_COUNT);
}
} catch (InterruptedException ie) {
OptimizeMe.debug(interrupted);
}
elapsed = System.currentTimeMillis() - started;
midlet.exitCanvas(exitStatus);
}
public void paint(Graphics g) {
g.setColor(COLOR_BG);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(COLOR_FG);
g.setFont(Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD | Font.STYLE_ITALIC, Font.SIZE_SMALL));
for (int i = 0; i DRAW_COUNT; i++) {
g.drawString(frameTime + ms per frame, getRandom(getWidth()), getRandom(getHeight()),
Graphics.TOP | Graphics.HCENTER);
}
}
private int divisor;
private int r;
public synchronized int work(int[] n) {
r = 0;
for (int j = 0; j DIVISOR_COUNT; j++) {
for (int i = 0; i n.length; i++) {
divisor = getDivisor(j);
r += workMore(n, i, divisor);
}
}
return r;
}
private int a;
public synchronized int getDivisor(int n) {
if (n == 0) {
return 1;
}
a = 1;
for (int i = 0; i n; i++) {
a *= 2;
}
return a;
}
public synchronized int workMore(int[] n, int _i, int _d) {
return n[_i] * n[_i] / _d + n[_i];
}
public void keyReleased(int keyCode) {
if (System.currentTimeMillis() - started 1000l) {
exitStatus = USER_EXIT;
midlet.running = false;
}
}
private int getRandom(int bound) {
// return a random, positive integer less than bound
return Math.abs(random.nextInt() % bound);
}
}
The above app is a simple MIDlet that simulates a simple game loop:
• work
• draw
• poll for user input
• repeat
¥§S !¨ $# © ¤¢#¨©¨!! ©
- 5. £§£¨£© ¥¨§¦ ¥¤£¢ ¡
w¥ £w€ £“¥U g‰ fƒy†
lW lW
Our loop continues for a finite number of iterations (LOOP_COUNT = 100) and uses the System
timer to calculate how long in milliseconds the whole exercise took, so we can measure and
improve its performance.
The time and the results of the work are displayed on a simple Form.
Use the Start command to begin the test.
Pressing any key will exit the loop prematurely.
The Exit command exits the application.
In most games, the work phase of the main game loop involves updating the state of the game
world - moving all the actors, testing for and reacting to collisions, updating scores, etc. In this
example, we're not doing anything particularly useful. The code simply runs through an array of
numbers and performs a few arithmetic operations on each, aggregating the results in a running
total.
The run() method also calculates the amount of time it takes to execute each iteration of the loop.
Every frame, the OCanvas.paint() method displays this value in milliseconds at 16 random
locations on screen. Normally you would be drawing the graphical elements of our games in this
method, but our code does almost the same as games.
¥§T !¨ $# © ¤¢#¨©¨!! ©
- 6. !¨ $# © ¤¢#¨©¨!! © ¥§X
`”ƒ“•˜”m ƒd€w©` w˜ £ƒ¦–ƒ‚h
`xƒ“y”ƒf˜”m` y–ƒƒx £w€ ¦–“h y‚¡“
ƒw˜‚m–£hƒ‚x—€h l `‘‰ ˆ‡† w˜“y“£© ˜”–“¢ ¨€…€„ §h‡@h` ƒ‚y y–ƒƒ† gS fƒy†
¤¢¦p¥s¤h ¢£i ¢ic¡pi Y
£§£¨£© ¥¨§¦ ¥¤£¢ ¡
- 7. !¨ $# © ¤¢#¨©¨!! © ¥§d
`••` ”˜ `d` ”˜ §`€` ˜y £ƒ—€w @x¥˜“”ƒyx@—
ƒd “i x£˜‚yƒ— ”¥˜@ ƒxƒ ”˜ §”ƒ“•˜”f ƒ‚y ¡w“x¥ ƒ”˜•ƒd ƒ£˜– ”¥˜@ ƒy€–x¥•d˜ y˜w ˜‡ F
xyxƒy ¡w“ww¥” ƒ”€ ¥˜@ ƒ“‚i —¥—“w“— € ˜y hm ƒ‚y w˜ @y“…“y–€ fƒƒ¦ £w€ x”ƒxi˜”d yƒw”ƒyw“ ƒ¦“
§xw˜“y€–“ff€ £w¥˜”¡¦–€d @w€ ƒx˜– ˜y yw€i y‚¡“— ¥˜@ §ƒd“xx˜f x€ —”˜•“w¥ x€ x¡w“‚y fƒƒ¦ ˜f
f¤¢¦p¥s¤h ¢£i ¢tptt¡¤ ¢¤s¥¢d tspic¤ch¢¤h itci¤shq#
e€y€£ ƒ‚y ƒy€”ƒwƒ¡ £w€ y–ƒ˜– ˜y ”ƒ“•˜”m ƒ‚y ”˜• §ƒ“‚i € ƒ¦€y @€— y“ §£wƒ ƒ‚y y€ `y“ ©` xxƒ”f ¥˜@ ”ƒy•4’
lW lW
w¥ £w€ £“¥U gT fƒy†
£§£¨£© ¥¨§¦ ¥¤£¢ ¡
- 8. !¨ $# © ¤¢#¨©¨!! © ¥§¨
xƒ—“y X ”˜•
f˜˜ ƒ‚y w“ e’ƒ¡€—vi€”£ ƒx¥ £w€ ƒ¡€—“ w€ ˜yw“ i€”£ ˜y f˜˜ ƒ‚y ƒ”˜•ƒd e’¡w“”yxi€”£ ƒx¥ ˜y x“ ƒ “—“yf˜
˜y @€i ƒwE £ƒ€– ¡w“ƒd e’yw“€f @”ƒ…ƒ w“ xƒ—“y X £ƒ€– x“ yv f˜˜ ƒ‚y w“ x“ e’¡w“”y†i€”£ y€‚y ƒ–“y˜™
yx”“• ¡w“‚y y‚¡“” ƒ‚y ¡w“˜£ y¥˜d€ ¦w“‚y ˜y ƒ—“y €”y ƒ ƒ¦€y §x—‚y“”˜¡€ xy“ £w€ w¡“xƒ£ ƒ‚y y€ ¦˜˜@
tspicrpqpihg ¦¢¡¢b £¢p fe tspicrpqpihg
e’¡w“”yxi€”£ xƒx¥ y€‚y
£˜‚yƒ— ƒ‚y ¡w“ “—“yf˜ @d y”€yx €‚x ƒg ¢¨T f¥ xƒ¦€y e’¡w“”y†i€”£ y€‚y ƒ–“y˜w §”ƒ‚y”¥• ¡w“¦€ƒ”U
x£˜‚yƒ— e’‘‚xƒ”•ƒ”ƒ–“…ƒ‡@€fx“‡ w“ ¢S‰ £w€ e’yw“€fx€…w€h@¢ w“ £ƒx¥ ¢ST y€‚y ”ƒ…˜–x“£ ƒg
¤¢¦p¥s¤h ¢£i qs¤¥ cic¡ ¡¢i ¢¦¦s ¢£i ¢tp¤s¦h c
£§£¨£© ¥¨§¦ ¥¤£¢ ¡
- 9. !¨ $# © ¤¢#¨©¨!! © ¥§p
fEm†fEI ƒ‚y ”ƒ¡w˜ ˜w x“ e’¡w“”y†i€”£
i˜w £w€ ƒ—“y €y˜y w“ w˜“y–¥£ƒ” g£ƒ¦”˜i x€‚ w˜“y€ “—“yf˜ ƒ‚y y€‚y y¥xƒ” ”ƒ“•˜”f ƒ‚y w“ —”“•w˜h
w¥ £w€ £“¥U gd fƒy†
gxi˜˜• x€ e’yw“€f @•“£˜¢ gX fƒy†
£§£¨£© ¥¨§¦ ¥¤£¢ ¡
- 10. £§£¨£© ¥¨§¦ ¥¤£¢ ¡
q tspicrpqpihg ¦¢¡¢b sb fF tspicrpqpihg hss¦ ¢£i ¥s i¡s
ƒf“y¥— f€ƒ” “i £˜‚yƒ— x“‚y ¡w“ “—“yf˜ w“ y”˜••ƒ @”ƒ…ƒ §‚xƒ”•ƒ” @”ƒ…ƒ w“ £ƒ€– x“ £˜‚yƒ— e’yw“€f
r
ƒg ewƒy•˜ @”ƒ… £ƒ€– x“ y€‚y £˜‚yƒ— ƒ‚y •˜ y¥˜ ƒ“’ f˜˜ ƒ‚y •˜ y¥˜ ƒ…€ƒ ƒi w€– y€‚g x£”€iƒ”
I
ƒxƒ‚y ƒ…˜— x yƒ@ £ƒ€– x“ e’yw“€f ƒ—“y@”ƒ…ƒ y–ƒjd˜ x–“‚f€” € £w€ ƒ¡€—v w€ §¡w“”y† € §yw˜k € ƒ”€–ƒ£
xx€– ƒ‚y •˜ f˜y ƒ‚y ˜yw“ £w€ £˜‚yƒ— ƒ‚y •˜ y¥˜
xƒd€“”€… xx€– €d˜¡ ˜y xƒd€“”€… £˜‚yƒ— ƒ¡w€‚– g¨ fƒy†
In addition to moving method variables to class variables, we shall change those variables that
are not changing at all to be constants (static final): We have made the Font object a public
constant. The same goes for anchors. Pre-calculating these things keeps those calculations,
however insignificant, out of our loop. We have also made the MESSAGE a constant. That's
because Java loves to create String objects all over the place. Strings can be a huge memory
drain if they're not controlled. Don't take them for granted, or you will probably bleed memory,
which can in turn affect performance, especially if the garbage collector is being called too often.
Strings create garbage, and garbage is bad. Using a String constant reduces the problem. Later
we'll see how to use a StringBuffer to completely stop memory loss from String abuse.
¥ § ‘ !¨ $# © ¤¢#¨©¨!! ©
- 11. !¨ $# © ¤¢#¨©¨!! © ¥ §
gxi˜˜• x€ e’yw“€f ƒ‚y ƒy€£f¥ g‘ fƒy†
gxi˜˜• x€ ”˜y–¥”yxw˜– ƒ‚y ƒy€£f¥ gp fƒy†
£§£¨£© ¥¨§¦ ¥¤£¢ ¡
- 12. !¨ $# © ¤¢#¨©¨!! © ¥ § F
”ƒ••¥U¡w“”y† ƒx¥ ˜y e’yw“€f ƒ‚y w“ w˜“y€wƒy€–w˜– ¡w“”yx ƒ‚y ¡w“¡w€‚h F
e’yw“€f w“ ”ƒy€ xƒ¥€…
£ƒ “• x€ —ƒ‚y ƒx¥ £w€ ”˜y–¥”yxw˜– ƒ‚y w“ ƒ–w˜ £ƒ–w€…£€ w“ x”ƒd—¥w —˜£w€” ƒ‚y ƒy€”ƒwƒ I o
ƒ¡€x¥ ”ƒy€ ”˜• —ƒ‚y ƒ”˜yx £w€ £ƒ–w€…£€ w“ y‚¡“ƒI £w€ ‚y£“g ƒ‚y ƒy€¥–€h o
gw˜“y€¥–€–ƒ”m
gw˜“y€ “—“yf˜ ¡w“i˜˜• ƒ‚y ¡w“˜£ ƒd €‚x ƒi §ƒx€‚f x“‚y wv
¤¢¥¥¡¢¢tp¤i0
si ¡ ¢tp¤i0 XY tspic¦¡ ¦c ¢¤h q tspicrpqpihg ¦¢¡¢b sb f2 tspicrpqpihg
ƒ—“y €y˜y w“ w˜“y–¥£ƒ” g£ƒ¦”˜i x€‚ w˜“y€ “—“yf˜ ƒ‚y y€‚y y¥xƒ” ”ƒ“•˜”f ƒ‚y w“ —”“•w˜h
w¥ £w€ £“¥U g fƒy†
£§£¨£© ¥¨§¦ ¥¤£¢ ¡
- 13. !¨ $# © ¤¢#¨©¨!! © ¥ § ‰
gxi˜˜• x€ xƒd€“”€… xx€– iƒw ££4 gF fƒy†
£§£¨£© ¥¨§¦ ¥¤£¢ ¡
- 15. !¨ $# © ¤¢#¨©¨!! © ¥ § T
ƒ—“y €y˜y w“ w˜“y–¥£ƒ” g£ƒ¦”˜i x€‚ w˜“y€ “—“yf˜ ƒ‚y y€‚y y¥xƒ” ”ƒ“•˜”f ƒ‚y w“ —”“•w˜h
w¥ £w€ £“¥U gS fƒy†
gxi˜˜• x€ e’yw“€f ƒy€£f0 g‰ fƒy†
£§£¨£© ¥¨§¦ ¥¤£¢ ¡