haskell / binary

Efficient, pure binary serialisation using ByteStrings in Haskell.
Other
106 stars 65 forks source link

optimize small Getters #124

Open winterland1989 opened 8 years ago

winterland1989 commented 8 years ago

After some profiling, i came to the conclusion that current running logic is too complex, in order to support bytesRead, we have two Decoder type, the overhead of runGetIncremental is noticeable when the getter is small(around 100ns compare to cereal on my machine).

This gives binary a disadvantage in various benchmarks, since lots of benchmark just focus on a single combinator, the overhead of running it render this kind of benchmarks meaningless.

There're cases we do need running small getters, but i haven't really need bytesRead yet. So let's find a way to improve bytesRead, or remove it ?

kolmodin commented 8 years ago

Advancing the buffer pointer was moved to the outer loop since that gave a large speedup. This was done a few years ago when the library switched to CPS. Since then other libraries have tried different approaches - IIRC attoparsec updates the pointer in the innermost loop and still has great performance. It's definately worth looking into. All in all binary is due for an overhaul to try out some "new" ideas and change of API.

winterland1989 commented 8 years ago

Yes, attoparsec encode Pos into the CPS Parser type. My intuition is that, by doing the same trick we can eliminate the extra Decoder type, and speed up runGetIncremental. I'll try to verify this when i got time.

winterland1989 commented 8 years ago

Partial resolved in #125 , now the overhead is low enough to not be a practical problem, but it still screws some single combinator benchmarks, for example the one in scanner package(which is quite meaningless anyway).

I think maybe we should document trade-offs of current approach somewhere, so that people won't mistakenly think binary is slow. Actually it's the fastest one in my benchmark.