性能优化1: 使用多个RO以减少反应时间 Performance Tip 1: Use Multiple Duplicated Remote Objects to Reduce the Average Response Time

All software is current The Idea

It seems to me that nobody has ever mentioned this technique in any document yet. Here it is. You can actually use multiple duplicated remote objects to reduce the average response time. Think each remote object as a thread, so the more threads you have the quicker the work gets done. The best part is that most of the time these threads are waiting for the network to response instead of consuming CPU cycles heavily. You can safely start two or even more threads as long as your server can handle them.

The Experiment

Experiment setup: On the server side, I have a Java class with an echo method:

/**
 * Simply returns the same object. 
 * Useful for checking flex serialization.
 * @param object
 * @return the same object (Client side: AS serialization of the object)
 */
public Object echo(Object object) {
	log.debug("echo: " + object + (object == null ? "" : " - class: " + object.getClass().getName()));

	try {
		Thread.sleep(1000 * 5);  // 5s.
	} catch (InterruptedException e) {
		e.printStackTrace();
	}

	return object;
}

Since both my server and Flex client are on the same computer, I mimic the network trip time using a delay of 5 seconds in the echo method.

On the Flex side, I use the following code to create 5 remote objects at runtime:

var ro1:RemoteObject = createRemoteObject("ieo", "http://localhost.:8080/BASIS_Web/messagebroker/amf", "c1");
var ro2:RemoteObject = createRemoteObject("ieo", "http://localhost.:8080/BASIS_Web/messagebroker/amf", "c2");
...

/**
 * Constructs a new remote object with a new channel.
 * @param roDestination Destination of the RemoteObject; 
 * @param channelURI the URI used to create the whole endpoint URI for this channel;
 * @param channelId the id of the channel
 */
public static function createRemoteObject(roDestination:String, channelURI:String, channelId:String):RemoteObject {
	var channelSet:ChannelSet = new ChannelSet();
	var channel:AMFChannel = new AMFChannel(channelId, channelURI);
	channelSet.addChannel(channel);
	var ro:RemoteObject = new RemoteObject(roDestination);
	ro.channelSet = channelSet;
	return ro;
} 

The Result

Here is  my testing result:

No. of Remote Operation Sent Remote Object(s) Used Total time
10 ro1 only 50.3s
10 ro1 and ro2 each sends 5 operations 25.2s
10 ro1, ro2, ro3, ro4, ro5 each sends 2 ops 10.3s

Note: I called all the 10 operations in a chunk and the total time is the time between the first operation is called and the last response is received.

The Conclusion

Clearly, the result shows that the total time is inversely proportional to the total number of remote objects used (ignore the small processing overhead).

This technique is useful if the client needs communicate heavily with the server through remoting. By reducing the response time, you can make the end user experience a much more sooth one.

Some notes: Initially, I tried to to set up more channels for a single remote object, but it seems that the remote object will only use one channel - other channels are used as fail-over back; You can create remote objects at runtime instead of compile time declaration; Always use load testing to determine the optimized number of duplicated remote objects.