May 28, 2009, 9:27 p.m.
posted by angryuser
PerformanceRight after interoperability, the questions I hear the most about designing Web services deal with performance. This isn't surprising, because XML is textual and obviously much larger than an equivalent binary layout would be. In fact, laboratory performance numbers comparing DCOM (Distributed Component Object Model) with ASP.NET Web Services back this up, as DCOM is almost ten times as fast when the logic being run is pure echoing of data, such as an echoString function. Nevertheless, don't interpret lab tests showing binary formats as faster as proof that you should use a binary format. Often, the performance gains are almost entirely lost once real-world conditions are factored in, such as marshaling, network latency, and the actual amount of processing time a single operation takes. That said, it would be a mistake to ignore performance completely. It's important to understand the performance considerations of your Web service. Coding standards and decisions you make up front can help to maximize the performance of the Web service, or Web service client.
Writing Performance-Oriented Code with .NETOne overriding recommendation I would make for writing code that performs well is to use the asynchronous pattern for all I/O operations, such as file, disk, and network access (including Web service calls). This pattern isn't at all difficult to use: You just need to know how to create delegates for callbacks. For example, imagine that you are calling a Web service operation called SubmitPO. When you use wsdl.exe to create a proxy class, three methods will be created:
public POReceipt SubmitPO(PO po);
public System.IAsyncResult BeginSubmitPO(
PO po,
System.AsyncCallback callback,
object asyncState);
public POReceipt EndSubmitPO(
System.IAsyncResult asyncResult);
The first thing to do is to write a function of your own that will be called when the operation is finished and has returned:
public static void MyCallback(IAsyncResult ar)
{
POClass class = (POClass) ar.AsyncState;
POReceipt receipt = (POReceipt) class.EndSubmitPO(ar);
//do something with the receipt
}
Next, you need to create an AsyncCallback that points to the callback function, and then call the BeginSubmitPO operation: POClass client = new POClass(); AsyncCallback cb = new AsyncCallback(SomeClass.MyCallback); IAsyncResult ar = client.BeginSubmitPO(po, cb, client); At this point, when the Web service call returns, the callback will be called, and the return value can be accessed. By doing this, you can continue to work on the calling thread. This means that your user interface doesn't need to become unresponsive; and even in nonvisual applications, you can call multiple services nearly simultaneously. Instead of ten serial calls of 1 second each, for an elapsed time of 10 seconds, you can call the ten services simultaneously and get it over in 1.1 seconds. Of course, your results may vary based on hardware and other factors. Message Size and Network LatencyOne of the fallacies that many developers fall into is trying too hard to optimize the size of a message. For example, a cursory flick of logic may make one think that if a Web service is running at 400 requests per second, then cutting the message size in half would make it run at 800 requests per second. On second thought, it's apparent that this is not necessarily true. In fact, the extra processing power needed to make the message smaller may actually slow down the service. Keeping an entire message under the MTU (Maximum Transmission Unit) size of a TCP/IP packet may result in a slight performance gain. In general, however, the thing to optimize is network latency. For example, even if you take your code's processing time from 0.2 seconds to 0.1 seconds, if the network latency is still 4 seconds, then the improvement doesn't make a big difference! Optimizing latency on the network, especially when the Internet is involved, is challenging—you have to examine the actual physical topology of the network involved. Figure shows the optimal network topology between a Web service and its client. It is an overly simplistic network, but the fact remains that from a latency standpoint, it is optimal. The typical Internet-based topology looks more like Figure, encompassing a large number of machines, such as bridges, routers, and hubs. The more you can get away from the topology in Figure and the closer you can get to the topology in Figure, the faster your Web service will respond to its clients. 1. A Development Network …
2. … and the Real Internet
How Important Is Performance?In the end, I highly recommend not worrying excessively about performance. It's important, and you should think about it up front. But the Internet and the Web are not conducive to high performance. No matter how much you do, you may never achieve your performance objectives. Even if you do, the cost for each gain in speed will take a logarithmic amount of work. Are you willing to spend a week to get a 1-percent gain? Do what you can, but don't expect miracles. |
- Comment

