It's weekend again and here's my update.
Using fcl-web's new-style routing, the program is now in one source file. It uses DumpRequest to echo the request to the client.
program HelloHeadersPure;
{$mode objfpc}{$H+}
uses
cthreads, httpdefs, httproute, webutil,
fphttpapp;
procedure doEchoRequest(aReq: TRequest; aResp: TResponse);
begin
DumpRequest(aReq, aResp.contents, true);
end;
begin
HTTPRouter.registerRoute('*', @doEchoRequest);
Application.Port:=8080;
Application.Threaded:=True;
Application.Initialize;
Application.Run;
end.
fcl-web also supports libmicrohttpd. Here's the equivalent program.
program HelloHeadersMu;
{$mode objfpc}{$H+}
uses
cthreads, httpdefs, httproute, webutil,
microhttpapp, custmicrohttpapp;
procedure doEchoRequest(aReq: TRequest; aResp: TResponse);
begin
DumpRequest(aReq, aResp.contents, true);
end;
begin
HTTPRouter.registerRoute('*', @doEchoRequest);
Application.Port:=8080;
Application.Options:=[mcoThreadPerConnection, mcoSelectInternally];
Application.Initialize;
Application.Run;
end.
I've named the pure Pascal version hhpure and the libmicrohttpd version hhmu.
Below are some figures using hey, a tool similar to ab, to get a feel of the relative performances.
This is hhpure running in Docker container on my laptop, 5000 connections.
Summary:
Total: 4.4411 secs
Slowest: 3.0444 secs
Fastest: 0.0006 secs
Average: 0.0233 secs
Requests/sec: 1125.8421
Total data: 14365000 bytes
Size/request: 2873 bytes
Latency distribution:
10% in 0.0011 secs
25% in 0.0014 secs
50% in 0.0019 secs
75% in 0.0028 secs
90% in 0.0048 secs
95% in 0.0083 secs
99% in 1.0273 secs
Now hhmu running in Docker container on my laptop, 5000 connections.
Summary:
Total: 0.7462 secs
Slowest: 0.1419 secs
Fastest: 0.0003 secs
Average: 0.0071 secs
Requests/sec: 6700.4482
Total data: 14300000 bytes
Size/request: 2860 bytes
Latency distribution:
10% in 0.0005 secs
25% in 0.0020 secs
50% in 0.0041 secs
75% in 0.0088 secs
90% in 0.0173 secs
95% in 0.0230 secs
99% in 0.0457 secs
Now for a slightly more 'real world' test. I run the timings from my laptop to a VPS running each Docker image in turn, with Caddy as the Internet-facing HTTPS reverse proxy in front. The VPS is 1 CPU with 2GB RAM. At any one time there are 7-10 Docker containers doing real world stuff, but the overall VPS system load is generally very low. I made no attempt to manage the load of the VPS while running these tests.
This is hhpure:
Summary:
Total: 25.3875 secs
Slowest: 0.9708 secs
Fastest: 0.1706 secs
Average: 0.2407 secs
Requests/sec: 196.9471
Total data: 15315000 bytes
Size/request: 3063 bytes
Latency distribution:
10% in 0.1780 secs
25% in 0.1836 secs
50% in 0.2009 secs
75% in 0.2881 secs
90% in 0.3221 secs
95% in 0.3560 secs
99% in 0.7131 secs
This is hhmu:
Summary:
Total: 23.1742 secs
Slowest: 1.2708 secs
Fastest: 0.1685 secs
Average: 0.2233 secs
Requests/sec: 215.7569
Total data: 15250000 bytes
Size/request: 3050 bytes
Latency distribution:
10% in 0.1732 secs
25% in 0.1754 secs
50% in 0.1818 secs
75% in 0.2381 secs
90% in 0.3088 secs
95% in 0.3210 secs
99% in 1.1814 secs
The two are now comparable. Going by the in-laptop local results, these runs' outcomes were dominated by the performance of the Caddy HTTPS reverse proxy and the network between my laptop and the VPS.