XML-RPC for C and C++

A lightweight RPC library based on XML and HTTP.

Copyright 2001 Eric Kidd. All rights reserved. The contents of this website may be distributed under the same license terms as XML-RPC for C/C++. Funding for the initial releases of XML-RPC for C/C++ was provided in part by First Peer, Inc.

SourceForge Logo

Performance

People often wonder how fast a system based on Xmlrpc-c (or indeed, anything with the XML-RPC protocol) can run. XML-RPC is known as a protocol that makes speed a very low priority, but C is known as a way to write programs that run faster than just about any other kind.

Naturally, there is no simple answer to the question, "how fast does Xmlrpc-c go"? There are so many variables in any application that it's almost irresponsible to report any number of RPCs per second or response time.

Nonetheless, some information is better than no information, so I ran some measurements and the results are below. I don't give enough information for you to reproduce the results and it's unlikely your application is similar to my test. Yet this should make your wild guess about what you can do with Xmlrpc-c a little less wild.

Also, the numbers are good for comparing a few of the options available with Xmlrpc-c.

General Parameters

In the test, both client and server use Xmlrpc-c facilities. The RPCs are trivial, like the "sample_add" examples in the source tree. There is no significant processing done above the Xmlrpc-c libraries on either side.

The client and server are on the same machine, so there is no physical network delay. There is nothing going on in the test besides computation, so the numbers are primarily applicable to a CPU-bound application.

The computer is a ca. 1999 personal computing class Linux machine. Linux says the processing speed is 696 bogomips.

Xmlrpc-c version is about 1.12.

Abyss

Here, we use true standard XML-RPC and a simple single-thread Abyss server, like the xmlrpc_loop_server example program in the Xmlrpc-c source tree. The client uses the Curl XML transport.

Note that in this configuration, there should be HTTP persistent connections; i.e. 100 RPCs in a row should all use a single TCP connection. But I didn't verify that it actually happened. Persistent connections should make a big difference, especially with a real network involved. See client library documentation for an explanation of what stars have to align for an RPC to hitch a ride on a pre-existing TCP connection.

Using C, a client program starts (exec()), does 100 RPCs, and exits in 380 milliseconds. With just one RPC, it's 26 ms. By calculation, this means the time for just an RPC is about 4 ms, about 280 RPCs per second.

The 4 ms response time breaks down (from the client's perspective) to 2ms of CPU time and 2 ms of waiting for the server. The waiting is presumably CPU time in the server. Remember there is no transit time in this setup.

Switching to C++ client and server, the 100 RPC run takes 1350 ms and the single RPC run takes 60, so the marginal RPC response time looks like 13 ms (triple that for C).

The 13 ms response time breaks down into 1.2 ms of client CPU time and 12 ms of waiting for the server. (I can't explain why the client uses less CPU time than in the C case, but the RPCs were actually a little different).

Packet Stream

Much of the CPU time involved in XML-RPC is in computing the HTTP protocol. One thing Xmlrpc-c's packet stream variation on XML-RPC does is eliminate HTTP.

In this section, we look at a test run using a packet stream client and server (like the pstream_client and pstream_inetd_client example programs in the Xmlrpc-c source tree). There is no Abyss (because Abyss is an HTTP server). We invoked the server and client with socketexec. (Like the mentioned example programs, the test programs require a connected TCP socket as input; the socketexec program is what creates that TCP connection for it).

The code is C++ (Note that there is no C library for packet stream).

It takes 280 ms elapsed time to run a client program that does 100 RPCs. A run that does 1 RPC takes 68 ms. The run includes starting and exiting the program, and socketexec.

This appears to mean it takes 2.1 ms elapsed time to do an RPC on an already existing packet stream connection, i.e. 500 RPCs per second.

I measured the CPU time for one RPC as .7 ms on the client side and .6 ms on the server side. That adds up to 1.3 ms rather than the 2.1 ms calculated above, but it's in the same ballpark.

More detailed measurement of the one-RPC run shows that all the Xmlrpc-c initialization and termination and the one RPC takes 10 ms of CPU time, so the rest of the 68 mentioned above is running socketexec and execing the client program.

TCP_NODELAY

As described in the manual, it is important to use the TCP_NODELAY socket option (-tcp_nodelay option on socketexec), and all the numbers above are with it.

When I failed to do TCP_NODELAY on one side, the throughput went down to 12 RPCs per second. When I neglected it on both client and server side, I got 6.