8

I am working on a Haskell application, running in the browser compiled with GHCJS, which communicates with a server, also written in Haskell, over websockets. Both programs share the same Haskell data type definition, and I “just” have to pick serialization format.

At the moment, for simplicity, the program runs on Read and Show, which works, but is obviously not ideal.

On the other hand, it is unclear if the usual contenders for fast serialization, such as the cereal library, which work on ByteStrings are actually going to be efficient in GHCJS. Furthermore, GHCJS’s API seems to make it hard to let ByteStrings interact with the binary Blob type that the JavaScript bindings to Websockets provide.

Generic code generation (using GHC.Generics) would be nice.

Has anyone solved this problem before? Possibly even benchmarked various serialization variants on GHCJS?

Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139
  • 1
    I just used cereal. I was using reflex-frp on the client, which provided a way of basically viewing a websocket as an input Event of ByteString and an output Event of ByteString. I didn't really have any particular performance needs though, and I didn't benchmark; I had the pieces lying around already (was using cereal anyway), and it just worked, so that was all I needed. – Ben Dec 07 '16 at 02:06
  • Guess I should look at `reflex-frp` for their websockets bindings. – Joachim Breitner Dec 07 '16 at 22:17
  • 1
    I do recall now though that I was using `https://github.com/reflex-frp/reflex-platform` rather than hackage, and that I had some frustrations till I figured out that the websocket stuff included in that was significantly different from what was released on hackage at the time (a couple of months ago). – Ben Dec 07 '16 at 23:01
  • What did you end up using? – Johannes Gerer Oct 19 '19 at 11:34
  • I don’t recall. I think the project did not go beyond hte `Read`/`Show` stage. – Joachim Breitner Oct 19 '19 at 11:51

1 Answers1

1

We were looking for a fast serializer/deserializer library in Haskell to store data in a reddis cache last year and eventually we ended up using ProtoBuf! That was partially because we already had ProtoBuf implementation of all of the objects that we wanted to serialize, but the performance was also much better compared to cereal/binary. By the time, store was non-existent.

The size and the speed of serialization/deserialization very much depends on your data as well. For instance, if you have lots of smallish (say in the range 1 to 100) 64 bit numbers, protobuf (because of its base 128 variant encoding) or even JSON could be more efficient than cereal or binary (that I guess use a fixed size for numbers regardless of their values).

There is also Typed-Wire that allows you to do serialization across a few languages, but I think it uses JSON as the underlying implementation.

i have no experience with GHCJS, but I'd recommend trying store first. Just make sure client and server have no little/big endianness incompatibility.

Hapal
  • 135
  • 5
  • Will the automatically derived `Generic` instances of the `store` library be Endian-safe? – Joachim Breitner Dec 07 '16 at 22:19
  • As far as I remember, `store` supposes that both encoder and decoder have the same endian (for the sake of performance). Most other encoding libraries do not make that assumption. It does not matter whether or not you use the generic implementation since the instances for basic types are typically implemented manually anyways. – Hapal Dec 07 '16 at 22:28
  • By the way, if you are looking for performance on the JS side, you may benefit from native JSON implementation as well. I am not sure how you can use a native JSON decoder rather than something like Aeson in GHCJS, but it must be doable. – Hapal Dec 07 '16 at 22:32