When dealing with remote objects, such as Enterprise JavaBeans (EJB), some of the biggest performance problems can be traced
to network traffic. A method call that has to be marshaled over a socket connection is going to be much slower than a method
call issued in local memory. The following piece of client code, which assumes that bean is a handle to an EJB, makes six remote calls (remember, red here stands for client code):
bean.setFirstName( "Thomas" );
bean.setLastName( "Davis" );
bean.setCity( "Boca Raton" );
bean.setState( "Florida" );
bean.setZipCode( "33487" );
bean.setCountry( "United States" );
This code has the potential to be a performance nightmare. Six calls to bean methods means six requests over the network. In the EJB implementations with which I have worked, all of the client-to-EJB communication within a single virtual machine instance takes place through a single socket connection. This is a bottleneck. When one client is talking to a bean, other clients (within the same virtual machine, sharing the single socket) are waiting for their turn. Waiting is bad. You want to avoid remote calls whenever possible.
One solution to this problem, the solution I am going to promote in this article, is to encapsulate the bean properties into
a single object, and then send that entire object back and forth between client and server (over the network). This lets you
put all of the get/set methods into the transported object and have them executed within the client's virtual machine -- in local memory rather
than over the network. The properties object must be serializable in order to be transported over the network, and it should be as compact as possible to ensure the fastest possible transfer
rate. Here is an example that encapsulates the properties that the above code modified (note that it's blue because it is
shared between the client and the bean):
public class BeanProperties implements java.io.Serializable {
private String firstName, lastName, city, state, zipCode;
public void setFirstName( String firstName ){
this.firstName = firstName;
}
// more 'set' methods for the other string values...
}
Using this technique, you can reduce the previous client example to only two remote calls. The first call retrieves the properties object from the bean, while the second sends the properties object back to the bean:
BeanProperties props = bean.getProperties(); // remote call #1
props.setFirstName( "Thomas" ); props.setLastName( "Davis" ); props.setCity( "Boca Raton" ); props.setState( "Florida" ); props.setZipCode( "33487" ); props.setCountry( "United States" );
bean.setProperties( props ); // remote call #2
This code is going to run more quickly due to the reduced amount of network calls. And any other processes that are sharing the same network connection will also run more quickly because they won't be waiting as often for this client to relinquish the socket.