From a very quick skim of "calico.rkt", I saw some potential small
optimizations (e.g., small copying and translation steps that could be
eliminated), but nothing obviously huge.
I assume that you're running "calico.rkt" from the command line when you
do "ab", not running within DrRacket.
My suggestion is to add the statistical profiler
("http://docs.racket-lang.org/profile/") to "calico.rkt", and see if
that points out a culprit.
One easy way to use the profiler is to have it instrument a single HTTP
request, and have it append a textual report to the end of the HTTP
response. If that doesn't catch the problem, then you can do some more
work to instrument many HTTP requests.
After the statistical profiler, you can then look at garbage collection
cycles.
One option that I keep in my back pocket is the bare-bones SCGI library
("http://www.neilvandyke.org/racket-scgi/"), since it's good to have an
alternative stack in case some situation demands different performance
tradeoffs than Racket "web-server". But I suggest first looking at
"calico.rkt" with the profiler.
I've mentioned a few analysis steps and such here, but hopefully the
very first simple one-HTTP-request profile diagnoses the problem.
Incidentally, your Racket code looks good.
Neil V.
--
http://www.neilvandyke.org/