hs-asn1 icon indicating copy to clipboard operation
hs-asn1 copied to clipboard

Improve memory efficiency

Open adinapoli opened this issue 8 years ago • 7 comments

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:

screen shot 2016-08-26 at 12 09 26

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 thebefore/after`:

screen shot 2016-08-30 at 11 29 09

screen shot 2016-08-31 at 15 02 38

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 a DList, to avoid expensive reverse 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 and BangPatterns to make certain accumulators strict in recursive functions
  • Inlined the definition for return, (>>=) and fail in the Get monad, as the cereal guys are doing these days
  • Added a very simple stack.yaml

adinapoli avatar Sep 02 '16 10:09 adinapoli

@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.

creichert avatar Nov 10 '16 01:11 creichert

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 😉

adinapoli avatar Nov 11 '16 08:11 adinapoli

Is there any interest in merging this patch?

mlongob avatar Sep 11 '17 21:09 mlongob

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

vincenthz avatar Sep 18 '17 13:09 vincenthz

I would likely cherry pick some of this; some parts are still undiscutably good things to have !

vincenthz avatar Sep 18 '17 13:09 vincenthz

@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 avatar Sep 18 '17 13:09 gridaphobe

@gridaphobe that sounds quite likely. I'm not sure that common builders were actually written already when asn1 got done :)

vincenthz avatar Dec 10 '17 22:12 vincenthz

archiving repository

vincenthz avatar Sep 20 '23 06:09 vincenthz