WebReference.com - Chapter 16 of Java Servlets Developer's Guide, from Osborne/McGraw-Hill (2/4)
[previous] [next] |
Java Servlets Developer's Guide
Avoid Debugging Statements
Many developers like to use System.out.println() for debugging. Sometimes it's just a lot easier to use this crude debugging method instead of firing up an IDE. Some developers will move the actual printing of debug messages to a common method so that it can be turned on and off:
public void debug(String msg)
{
if (debugEnabled)
{
System.out.println(msg);
}
}
You can even add a timestamp to each message when you print it, or change the target of the message (to a file, for example). In your servlet, you could then simply call the debug routine:
debug("The value is " + someValue);
To get debug messages, you simply need to make sure that debugging is enabled in the debug() method. Sounds great, doesn't it?
Look out! This is a nonobvious performance drain. You will end up performing String concatenation of the message to be debugged before you realize whether the message will even be used. If debugging is not enabled, you will still end up creating unused String messages. I'm not suggesting that you throw away using a debug() method, but you should provide some way for the caller to check to see if debugging is enabled first before calling the debug() method:
if (isDebugEnabled())
{
debug("The value is " + someValue);
}
Avoid Use of StringTokenizer
A common performance hotspot that I have run across when using profiling tools is the use of java.util.StringTokenizer. While there is convenience in using the StringTokenizer, there is a tradeoff in performance. If you are using a StringTokenizer simply to scan for a single delimiter, it is very easy to use simple String functions instead.
Consider the following example, which uses StringTokenizer to parse a String:
import java.util.StringTokenizer;
public class TestStringTokenizer
{
public static void main(String[] args)
{
String s = "a,b,c,d";
StringTokenizer st = new StringTokenizer(s, ",");
while (st.hasMoreTokens())
{
String token = st.nextToken();
System.out.println(token);
}
}
}
Executing this application will result in the following output:
a
b
c
d
The following code replaces the StringTokenizer with a loop that uses String.indexOf() to find the next delimiter:
public class TestIndexOf
{
public static void main(String[] args)
{
String s = "a,b,c,d";
int begin = 0;
int end = s.indexOf(",");
while (true)
{
String token = null;
if (end == -1)
{
token = s.substring(begin);
}
else
{
token = s.substring(begin, end);
}
System.out.println(token);
// End if there are no more delimiters
if (end == -1) break;
begin = end + 1;
end = s.indexOf(",", begin);
}
}
}
Is it easier to read and understand? Definitely not, but it is much more efficient than using the StringTokenizer. Life is full of tradeoffs; you sometimes must choose between readability and performance.
Avoid Unnecessary Synchronization
You always need to remember that servlets operate in a multithreaded, multiuser environment, with the multiple threads working with a single instance of your servlet. When you decide to synchronize a block of code, it will result in only a single thread being able to operate on your servlet at any point in time.
There are certainly cases in which you need to synchronize access to a particular block of code, such as generating a unique ID or atomically updating a series of counters. Instead of synchronizing an entire method (or worse yet, an entire class), synchronize only the blocks of code that really need to be synchronized. It is easy to synchronize an entire method just to be safe; try to avoid this if at all possible.
[previous] [next] |
Created: July 31, 2002
Revised: July 31, 2002
URL: https://webreference.com/programming/java/servletsguide/2.html