Download (direct link):
Manually Inline Methods. Lines 51 to 54 were previously in the addMode() method, and instead we inlined the method within the createURL method.
Minimize Method Calls. Inlining all of the addXXX methods demonstrates minimizing method calls. This should especially be followed for any method calls inside of loops (like a call to check length() or size()).
// - deleted replaceString() — No Change.
092: public static final String httpGet(String sURL) throws 2
094: ticker.reset("Started Timer in httpGet()");
095: // get the connection object
Listing 22.6 (continued)
J2ME Performance and Pitfalls 195
096 System.out.println("url: " + sURL);
098 HttpConnection con = (HttpConnection) Connector.open(sURL);
099 int respCode = con.getResponseCode();
100 System.out.println("Response code: " + respCode);
101 InputStream in = con.openInputStream();
103 // lazy instantiate!
104 if (baos == null)
105 baos = new ByteArray0utputStream(1024);
108 if (buf == null)
109 buf = new byte;
110 String response = null;
111 int cnt=0;
112 while ( (cnt = in.read(buf)) != -1)
116 response = baos.toString();
117 ticker.printStats("Method httpGet()");
118 return response;
Listing 22.6 (continued)
The httpGet() method demonstrates three optimizations:
Line 92 declares the method final and static.
Lines 104 and 108 demonstrate lazy instantiation. Also, lines 105 and 109 guess the size of objects to avoid resizing—though ByteArrayOutputStream could be better sized with better sampling of average query sizes.
Read More than 1 Byte from a Stream at a Time. All network connections will buffer more than a single byte so reading larger chunks of data is more efficient.
Here are some additional optimization tips:
Avoid String Concatenation. String concatenation has been proven extremely slow, so use StringBuffers or streams to avoid this. This can be better taken advantage of in this application.
Avoid Synchronization. Synchronization is slow because of the overhead of implementation the thread controls.
If adding by 1, int++ is the fastest operation. This is faster than expressions like "I = I + 1;".
Improve Perceived Performance. Use progress meters to inform the user that the computer is active.
196 Item 22
Only Include Necessary Classes. To conserve memory required to store your application, only include necessary classes in the deployment archive.
Use Shift Operator to Multiply by 2. The shift operator is faster than the multiplication operator.
Avoid Casting. Casting is expensive, so have methods return only one type.
Use int as Much as Possible. Other types like byte, short, and character are promoted to an int. So eliminate the promotion by using ints directly
Avoid Using Exceptions. Exceptions require additional checking by the VM, so your code will be faster using more traditional procedural programming (with status returns).
The new, optimized code runs extremely well within 128 KB. Here is a run of the code demonstrating that by performing three queries and multiple showing of details:
Started Timer in doAmazonSearch(). Free Memory: 1087 60 Started Timer in httpGet(). Free Memory: 102160
url: http://xml.amazon.com/onca/xml?v=1.0&t=webservices-20&dev-t=D3AG4L7PI53LPH&KeywordSearch=daconta&mode=books&type=lite&page=1&f=xml Response code: 200
Method httpGet(): 8572. Free Memory: 35372 Method doAmazonSearch(): 8773. Free Memory: 32792 Started Timer in showDetails(). Free Memory: 75040 Method showDetails(): 20. Free Memory: 68768 // - removed second query for brevity
Started Timer in doAmazonSearch(). Free Memory: 63284 Started Timer in httpGet(). Free Memory: 60692
Response code: 200
Method httpGet(): 8502. Free Memory: 23512 Method doAmazonSearch(): 9143. Free Memory: 21244 Started Timer in showDetails(). Free Memory: 63736 Method showDetails(): 1082. Free Memory: 57560 Execution completed successfully 1578454 bytecodes executed 750 thread switches
324 classes in the system (including system classes)
2491 dynamic objects allocated (344132 bytes)
600 garbage collections (283784 bytes collected)
Total heap size 131072 bytes (currently 56276 bytes free)
Figure 22.6 displays MicroAmazonSearch being emulated on a BlackBerry device.
J2ME Performance and Pitfalls 197
Figure 22.6 MicroAmazonSearch emulated on a BlackBerry.
Copyright © 2002 Research In Motion Limited.
In conclusion, this pitfall has ported a Swing application to the J2ME platform in order to reveal two categories of pitfalls: a bias to programming for the J2SE platform and pitfalls caused by API differences. Lastly we covered and demonstrated over 20 techniques for optimizing J2ME code.
The Web Tier
'The original impulse for modularity came from a desire for flexibility, in particular