Designing High-Performance ISAPI Applications
ISAPI is the highest-performance interface for Web applications. If you create an ISAPI extension or filter, chances are that it will outperform ASP scripts or even components performing similar tasks.
However, the inherent speed of the ISAPI interface does not mean that you can ignore performance and scalability considerations. Indeed, ISAPI cannot utilize much of the application support services provided by ASP and COM. If you would like your ISAPI application to maintain session state, for instance, much of that session-state functionality would have to be implemented by you.
Here are some suggestions for improving the scalability and performance of your ISAPI extensions:
- Avoid ISAPI filters, unless adding an ISAPI filter is absolutely necessary to your application architecture. You should especially avoid filters that perform processing on raw incoming or outgoing data. If you determine that a filter is absolutely necessary, be sure to carefully optimize the main code paths through the filter event notification code.
- Create your own worker thread pool, so that the main I/O threads can be freed to accomplish other tasks. This option is available only for ISAPI extensions, and not for ISAPI filters. For more information about how IIS processes requests, see IIS Request Processing. A sample that demonstrates a worker thread pool, implemented in an ISAPI extension, is available in ISAPI Examples.
- Consider using asynchronous operations and I/O completion ports, when feasible. IIS supports asynchronous reading and writing by using the I/O completion ports, available in Windows NT 4.0, and Windows 2000 or later. Depending on the type of I/O operations being performed, asynchronous operations can make better use of the CPU time available, and generally work particularly well when implemented using a worker thread pool. For more information, see Asynchronous I/O Processing.
- ISAPI extensions should use the Win32 TransmitFile function, exposed by the HSE_REQ_TRANSMIT_FILE ServerSupportFunction.
- Use Connection: Keep-Alive headers. Keeping persistent HTTP connections will provide better performance than using non-persistent connections, in most cases. For more details, see Keep-Alive Connections.
- Minimize need for thread synchronization by maintaining state information with the request context. If thread synchronization is required, make sure that critical sections are kept short.
- If your ISAPI application uses the heap intensively, consider other heap alternatives. Intensive use of the Windows® heap can cause resource contention. Several memory allocation alternatives are worth exploring, including:
- Heap Partitioning, accomplished by creating multiple custom heaps, in addition to the default process heap. Each custom heap would then be controlled by a separate, non-global lock, and lock contention would be reduced.
- Cached Allocation, which involves using custom allocation operations that operate at a middle layer between the object users and the heap. Calls to the Win32 heap are made infrequently, and only for large memory blocks. These blocks are then subdivided and managed by the custom allocator.
- Stack Allocation, using the C run-time function _alloca to allocate memory for your objects on the stack instead of the heap. This method is feasible only for relatively small objects, because the space available on the stack is limited. In addition, your newly allocated object will be available only within the current functions, or functions called by that function. Once the current function returns, the storage allocated on the stack will be lost.
- Object Encapsulation, accomplished by simply incorporating a buffer as a member data structure of a class. This buffer is then used for tasks that would otherwise require accesses to the Win32 heap.
- Avoid using global locks within your ISAPI, if possible. Global locks can often adversely affect scalability.
For more information about ISAPI extensions and filters, see Developing ISAPI Extensions and Filters, and the ISAPI Reference.