Serialisation options with ASP.NET Core
I have been taking a look at the serialisation options available to a .NET Core app in order to see if it is worth us trying something new. Our current app uses ASP.NET web api and serialises as JSON over HTTP using the default built-in formatters.
Test application
I tried a little test serialising various amounts of data over the wire
- A ~8Mb string containing serialised market data (spots, vols, holiday calendars)
- A complex type representing a deal containing ~20 fields and nested types
I span up a few little servers, each serving this data over a different format
- JSON from an ASP.NET Core app running Kestrel
- As above but compressed using GZIP, with “Optimal” and “Fastest” compression level
- ServiceStack using proto-buf
- gRPC
I ran each test with client and server on the same machine then again with the client on a remote box.
Results
I ran each test 100 times, the result is the average time per call in ms.
localhost
Running client and server locally
Test | gRPC | ASP.NET Core / JSON (Uncompressed) | ASP.NET Core / JSON (Compressed Optimal) | ASP.NET Core / JSON (Compressed Fastest) | ServiceStack / proto-buf |
---|---|---|---|---|---|
8Mb string | 57 | 412 | 330 | 218 | 294 |
10 deals | <1 | 29 | 29 | 30 | 28 |
100 deals | 5 | 31 | 30 | 28 | 36 |
1000 deals | 48 | 108 | 91 | 80 | 119 |
remote
Running client remotely, servers locally
Test | gRPC | ASP.NET Core / JSON (Uncompressed) | ASP.NET Core / JSON (Compressed Optimal) | ASP.NET Core / JSON (Compressed Fastest) | ServiceStack / proto-buf |
---|---|---|---|---|---|
8Mb string | 798 | 913 | 344 | 238 | 827 |
10 deals | 14 | 29 | 49 | 28 | 46 |
100 deals | 15 | 45 | 50 | 29 | 88 |
1000 deals | 60 | 186 | 96 | 88 | 172 |
gRPC Compression
These results imply that proto-buffer format (gRPC and ServiceStack here) does not compress payloads: over-the-wire time is comparable to uncompressed JSON. I believe it is possible for both formats to compress data, I just can’t work out how! I opened a StackOverflow question to try and find the answer: gRPC compression in C#.
I suspect that gRPC will be by far the quickest format, if I can get compression enabled.
Conclusions
This is too simplistic a test to draw firm conclusions, but I can raise a few suggestions and explore them further later.
- gRPC is very fast but suffers when fields have a large amount of data. If I can get compression enabled I suspect this will be the clear winner
- Proto-buf on ServiceStack is very fast but again suffers with large fields (compression would help here too)
- ASP.NET Core’s JSON serialisation is very fast, and using gzip compression makes this the fastest format at the moment
- With the type of payloads we have higher levels of compression hamper performance (for gzip-ed JSON). Setting the compression level to “fastest” costs little in over-the-wire latency but gives a significant speed improvement
So given the lack of compression in gRPC I don’t think it is that usable for us, yet. We also lose the transparency and hackable ease that JSON over HTTP gives (i.e. being able to view an endpoint in the browser).
misc (3) netcoreapp (10)