![]() | |
Tips For Improving Code Performance By Sudhir Ancha In the end after the project is completed people spends thousands of
dollars trying to buy some code optimization tools and then spend more money tracing the code and fixing the performance issues.
2. When joining couple of Stings use StringBuffer instead of String. Instead of writing Write it as
If you know the Max Length of the String Buffer initially then use the number. For Example in the above scenario, the initial length of the StringBuffer is set to 50. This saves lot of over head since when length of the StringBuffer needs to be increased, then StringBuffer has to allocate new Character array with larger capacity, copy all the old contents into new array and discard the old array (during GC). To avoid this over head declare the approximate size of StringBuffer initially. Also don't over allocate. Memory is precious at runtime.
3. Don't try to convert Strings to upper or lower case for String comparison. For example do not do, str1 =a.toUpperCase(); Instead use, Again do not use equalsIgnoreCase() if equals() can be used. It adds another level of comparison while performing String comparison.
4. For converting String to bytes do not use method
getBytes(). While handling HTTP strings most of the times its normal ASCII characters.
For example do not use getBytes() method can handle any character encoding. But that power is not required for HTTP transactions most of the times. You can create you own method for handling only ASCII characters,
Next you can use this method as
5. For converting bytes to String, do not use the String This method works only for ASCII data, but the performance is really good. In HTTP protocol most of the times we deal with with only ASCII data. Note : Although this method is deprecated, it might be a while before this method is totally removed, unless alternative comes for ASCII only data.
6. StringTokenizer is one of the most popularly used function in Java.
It really gives the flexibility of parsing Strings with parsing capability of
multiple string length delimiter. For example it can parse Strings separated by "bqr" as delimiter as follows, But then there's always overhead during this operation. Since this has to compare each character, if it belongs in the set of delimiters. Instead you can you this method, if Strings need to be delimited only by a single character,
Our Tests reveal that the above method works almost 4 times faster than StringTokenizer, because of less overhead. But use this method with caution, since you might be loosing maintainability of your program.
7. Don't repeat the same function in conditional statements. For Example instead of writing for (int i=0 ; i < s.length; i++) {
8. In the String Class prefer charAt() method instead of startsWith() method. String class provides this method to decide if the String starts starts with given Sub string. From performance perspective, startWith() makes quite a few comparisons preparing itself to compare it's prefix with another string. So instead of writing,
9. Instead of writing, instead of creating new String object and appending them together in different steps.
10. Don't create objects unless required. For example do not declare
11. Do not declare the objects twice. For example in the
following code snippet, The compiler generates the following code for the Constructor, public classx {
12. In the conditional statements, the conditions are evaluated in
the order they are placed. For example if we declare as, boolean editmode = curStats1&& curStatus2; In the above statement getDataStatusFromDataBase() is not called if edit Mode is true.
13. For Large Scale enterprise applications, it is common to add new
Features and remove old features. if possible, if the old feature codes are never
going to be used, then remove the old code. Don't try to place old code in,
14. Vector provides the following methods to insert elements. Out of these try to avoid using methods, addElementAt( e, index) and add(index, e). The way these methods work is , all the elements are moved down between the insertion point and the end of the vector, making space for the new Element. The same works for deleting element at a Particular index. If possible, if these features are required, then try to use a different Data Structure if possible.
15. If the approximate size of the Vector is know initially then use
it. Instead of declaring Vector as, This method indicates initial capacity of Vector is 40 and increment by 25 elements per expansion. The way the Vector is expanded is, a new Vector of double the size of currentVector is created, all the Elements in the old Vector is copied to the new Vector and then the old Vector is discarded. (During GC). This has major effect on performance. So if the initial size of the Vector is known, use it. Same goes for the size of Hashtable and related Data structures.
16. Avoid using the Enumeration
class. The way Enumeration class is used is, In this code,
enum.hasMoreElements() takes lot of processing
time. Also for enum.nextElement() , enumeration class has to do lot of
processing internally like incrementing the internal Counter etc.
17. If the code is executing in a SingleThread, then use
ArrayList instead of Vector. All the methods
in Vector are Synchronized. For example for the following methods, In the Vector class, the elementAt() method explicitly verifies that the internal array index does not fall out of bounds. Methods in ArrayList leaves the task to user and are not Synchronized. This makes the execution faster.
18. Couple of times it becomes
necessary in code to retrieve element at a particular position in the Vector
and then remove that Element. Code for this one would be, In such a scenario, use the following code This returns element at index position and then removes that element from Vector. This saves call to elementAt() method.
19. In
Hashtable couple of
times we try to get Element with particular key and if it does not exist, then we
try to create new Element and insert that Element into Hashtable.
Sometimes code is written as, Here, we made performance overhead by calling these two methods on the same
Hashtable,containsKey() and get(). Both these methods do the same
thing, except containsKey() returns true/false and get()returns the actual Element. If the
Hashtable is of considerable size
then the overhead is high. Instead write the code as follows,
20. Cache Data as much as possible both on the Server and Client side as much as possible. For example do no try to get Data from Database every time which is hardly going to change for a long time. Either store it in local text or properties files or cache it for a pre defined interval once it is read from Database.
21. InetAddress.getHostAddress() has a lot of new operations. It creates a lot of intermediate strings to return the host address. Avoid it, if possible.
22. java.util.Date has some performance problems, particularly with internationalization. If you frequently print out the current time as something other than the (long ms-since-epoch) that it is usually represented as, you may be able to cache your representation of the current time and then create a separate thread to update that representation every N seconds (N depends on how accurately you need to represent the current time). You could also delay converting the time until a client needs it, and the current representation is known to be stale.
23. Avoid java.lang.String.hashCode() . If the String's length exceeds 16 characters, hashCode() samples only a portion of the String. So if the places that a set of Strings differ in don't get sampled you can see lots of similar hash values. This can turn your hash tables into linked lists!
24. Good Design is very important for any project. In most applications, good performance comes from getting the architecture right. Using the right data structures for the problem you're solving is a lot more important than tweaking String operations. Thread architecture is also important. (Try to avoid wait/notify operations--they can cause a lot of lock contention in some VMs.) And of course you should use caching for your most expensive operations.
25. This is one of the most common mistakes. A lot of people do something like the following:
debug("Debug Comment: " + var1 + var1 + "Current Value");
public static void debug(String s) {
System.err.println(s);
}
Then they think that they've turned off debugging overhead. Nope! If there are
enough debugging statements, you can see a lot of time spent in creating new
strings to evaluate "Debug Comment: " + var1 +
var1 + "Current Value", which is then tossed after calling
debug .
|