Good Coding Practice

 < Free Open Study > 

Programmers who write poor code can wreck the performance and scalability of even the best-designed system. In this section, we will cover good practices that will help you to write efficient servlet code (although the following tips are equally relevant to any Java code).

Using Classes

In this first section we'll consider how we should approach coding classes.

Use Shallow Inheritance Hierarchies

Deep inheritance hierarchies impose extra burden on the VM (virtual machine) for executing all of the superclass constructors. To avoid this use shallow inheritance hierarchies. One of the basic lessons of object-oriented programming is that object composition is preferred to class inheritance.

Use Classes From the Collections Framework Instead of Vectors

The classes from the collection framework like ArrayList, HashMap, and so on are faster than the Vector class. This is because all of the methods on the Vector class are synchronized to make them thread safe whereas the classes belonging to the Collections framework are not thread safe.

Use Reflection Sparingly

Using reflection extensively in your code can degrade the performance of your system. However, JDK 1.4 offers considerable performance improvement when using reflection.

Avoid SingleThreadModel

Avoid making your servlets implement the SingleThreadModel interface. It is always better to write thread-safe code.

Use Stateful Session Beans Sparingly

Stateless session beans are always more efficient than their stateful counterparts. Use stateful session beans only if you want the state to be maintained between public method calls.

Using Variables and Operators

This section contains some guidance for how you should approach the use of variables and operators in your code.

Local Variables are Faster to Access

Local variables are faster to access than instance variables, because they are stored in the stack instead of the heap.

Avoid Declaring Variables Inside Loops

It is always faster to declare variables outside a loop even if they are used only inside the loops, because we then we don't instantiate an object with each new loop. For example:

    for(int j = 0; j < 10; j++) {      MyObject myObject = new MyObject(j);      myObject.someMethod();    } 

The above code may be rewritten as shown below to improve performance.

    MyObject myObject;    for(int j = 0; j < 10; j++) {      myObject = new MyObject(j);      myObject.someMethod();    } 

Use the final Modifier for Immutable Instance Variables

Defining instance or class variables that are only used for storing constant values can improve performance.

Use char Arrays

Character arrays are faster than strings and string buffers.

Use StringBuffer Instead of the + Operator

String objects in Java are immutable. This means that whenever you invoke a method on a String variable that amends its contents, the original contents of the String is left unaltered and a new string that contains the result of invoking the method on the original content is created. If your servlet performs content generation and involves quite a lot of string concatenation it is better to use a StringBuffer rather than the + operator. For example:

    String myString = "";    for(int i = 0; i < 1000; i++) {      myString += "test";    }    System.out.println(myString); 

The above code snippet will perform lot better if written as shown below:

    StringBuffer myString = new StringBuffer();    for(int i = 0; i < 1000; i++) {      myString.append("test");    }    System.out.println(myString); 

Compound Operators are Faster

Compound operators generate less byte code and are hence faster than normal operators.

    int j = 10;    j = j + 20; 

The above code may be rewritten as:

    int j = 10;    j += 20; 

Using Methods

In this section we'll discuss a few hints for good coding practice related to method design.

Use Monitor Locks Sparingly

Only lock (synchronize) the required bits of code, to avoid lock contention that negatively impacts upon performance in a multi-threaded environment. For instance:

    public synchronized void myMethod() {      //Thread safe code;      //Thread unsafe code;    } 

The above method may be rewritten as

    public void myMethod() {      //Thread safe code;      synchronized(this) {        //Thread unsafe code;      }    } 

Method Inlining

Declaring a method as final, static or public will help the Java compiler optimize the code during compilation without worrying about late binding.

Use arraycopy() for Copying Arrays

Using the arrayCopy() method defined in the java.lang.System class is much faster than looping through the source array and copying the items. This is because this method is defined natively.

Use notify()

Use the notify() method instead of notifyAll() for notifying the threads waiting on monitor locks, as it is faster.

Use charAt()

The charAt() function is faster than the startsWith() method in the String class, if you are comparing only one character. In other words, the following code:


is slower than:

    System.out.println("Meeraj".charAt(0) == 'M'); 

Using Databases

The way that you enable data access within your application often has a major effect on your application's performance. We will discuss this in more depth later in the chapter. First, here are some coding tips related to database access.

Select Only Required Columns

When you select columns from a database table using JDBC, select only those columns you need. This will restrict the amount of data transferred between the data server and your application, improving performance.

Use Appropriate Getter Methods on ResultSets

When retrieving data from ResultSet objects, use the appropriate version of the get method corresponding to the expected type of the column, instead of using generic getObject() and getString() calls. This will avoid overheads associated with unnecessary type conversions.

Use JDBC PreparedStatements

PreparedStatements are considerably faster than normal statements in JDBC, if the driver supports pre-compilation of PreparedStatements.

Other Miscellaneous Coding Tips

Here are some other useful rules-of-thumb for when you are coding.

Optimize During Compilation

Optimize your code during compilation using the -O option. However, you should note that this may hinder byte code debugging and increase class size.

Use Short Transactions

Make your transactions as short as possible. This will release locks on objects more quickly, thereby reducing lock contention.

Tune Heap Size

Use the -Xmx and -Xms options with the JVM to set the maximum and initial amount of heap as required.

Use Asynchronous Logging

Use asynchronous logging to improve performance. This means sending a log message to an in-memory buffer like a JMS destination, which is later written to the disk by a different thread.

Use the transient Modifier

To speed up serialization, declare the fields that need not be serialized, using the transient modifier.

Use Externalization

Use externalization to create faster custom serialization algorithms.

Use Non-blocking I/O

JDK 1.4 provides options for non-blocking I/O that can improve scalability and performance.

Streams are Faster

Streams that deal with eight bit data are faster than readers and writers that use Unicode format. Use readers and writers only if you need internationalization.

Cloning is faster

Cloning is a very effective way of creating a huge number of similar objects, rather than using the new operator.

 < Free Open Study > 

Professional Java Servlets 2.3
Professional Java Servlets 2.3
ISBN: 186100561X
EAN: 2147483647
Year: 2006
Pages: 130 © 2008-2017.
If you may any questions please contact us: