hs-asn1
hs-asn1 copied to clipboard
Improve memory efficiency
Hey @vincenthz !
This is one of a series of PR hitting different projects (namely hs-pem
, hs-asn1
and hs-certificate
) aimed at improving the memory/time efficiency of these libraries and therefore reduce the memory footprint of virtually all the Haskell servers using tls
and http-client-tls
(which has reverse deps toward these libs).
I started by profiling the memory allocation of my production web server, and I've noticed that most of the memory footprint was coming from getTlsConnection
:
Digging deeper I have isolated most of the memory consumption as coming from the MacOS
module, which could be pinned down to the parseSigned
function (for which I will open a separate PR on hs-certificate). But despite that, I was able to reduce memory footprint quite a bit by using very simple transformations on this project. An example of the
before/after`:
Memory consumption went down from roughly 168,573,032
to 141,581,480
(consistently),
and times seems to have improved as well. Considering it's quite a big patch, I will try to break it down. I have:
- Replace the inner data structure of
ParseCursor
to use aDList
, to avoid expensivereverse
and++
- Removed
mplusEither
which has exactly the same semantic of>>=
(unless I'm missing something - Used
foldl'
where appropriate - Used
UNPACK
and strict fields, where appropriate - Used
seq
andBangPatterns
to make certain accumulators strict in recursive functions - Inlined the definition for
return, (>>=) and fail
in theGet
monad, as thecereal
guys are doing these days - Added a very simple
stack.yaml
@adinapoli I also stumbled upon a similar issue in #20
I'm not convinced they are the exact same issue but it might be a good test case for your current changes. There is a fully working example in that issue.
Hey @creichert !
Thanks, that's very interesting! I am a bit swamped these days, but I guess it would be easy enough to do a before/after
comparison. I will try to keep you posted! If I slack off, feel free to keep me honest 😉
Is there any interest in merging this patch?
I think this ship has sailed for this specific patch, but asn1 is likely to use better primitives in a near future (I hope), so it would likely improve from there
I would likely cherry pick some of this; some parts are still undiscutably good things to have !
@vincenthz Do you have any specifics on the better primitives? One thing I've noticed is that the encoder is probably doing a bunch of unnecessary allocations by constructing intermediate bytestrings rather than using builders.
@gridaphobe that sounds quite likely. I'm not sure that common builders were actually written already when asn1 got done :)
archiving repository