Migrating to Jason from Poison

I currently work on an Elixir/Phoenix API that talks directly to a React frontend. In needing to encode some ecto structs into JSON and pass them to be stored in a JSONB column in Postgres. We ran into issues where the meta field and the non-loaded associations would raise errors in Poison. We found a few blogs and videos on how to handle this, but with the complex data structure that we were creating, these methods didn’t help. I did some research into alternate JSON libraries and discovered Jason, it claims to be much faster than Poison and more importantly it can pass the fields you need to be encoded specifically, rather than it being undeclared or declared at the ecto schema level (where it wouldn’t work for our case).

`The parser and generator are at least twice as fast as other Elixir/Erlang libraries (most notably Poison).`

https://github.com/michalmuskala/jason

This is a bold claim made by the creator of the library. Then I read a little further, apparently it was extremely easy to migrate to over the alternative which comes by default in Phoenix, on the count that it had been designed that way. This was quite interesting, let's test out just how easy it would be to migrate. It turns out it was as easy as adding the dependency and changing the json parser in the config. Just like that it was done, all the tests passed and very slightly faster.

What makes it even better is just how easier it is to switch!

https://github.com/michalmuskala/jason

https://github.com/michalmuskala/jason

from: https://github.com/michalmuskala/jason

from: https://github.com/michalmuskala/jason

Thats all you have to do to switch to Jason.


Now for the benchmarks

Unless I can prove it was faster, there's not really much point in doing it and no one else on the team will approve it for a PR. I compared 6 queries of various complexities and the test suite. No this isn’t the most scientific process, but it at least showed me the before and after of the most common things we do with our API. Now I can’t show all the queries hence the 1-4 but I can describe how complex they are.

Screen Shot 2018-11-16 at 10.36.47 pm.png

*Note: these were run locally

Test suite: Comprises of various unit tests and integration tests. It contains roughly 350 tests in total. We saw a 2% drop in time to run, which isn’t bad as most of the tests wouldn’t ever encode or decode JSON.

Login: We saw a massive drop of 31% in the time to run for this query, that's extremely impressive, which I’m surprised about.

Dashboard: This query is a fantastic example of the performance improvements. It’s a good chunk of data and it relies heavily on encoding and decoding, as a result it saw a big 34% improvement.

Query 1: is an enormous query that really smashes the database. I was surprised that the improvement was only 2% as it contains a huge amount of data so if you improve the timeit takes to encode and decode the large amount of data would logically see a big improvement in time, but it didn’t, it must not rely as heavily on JSON transformations as I thought.


Query 2: This query saw no improvement which was interesting, it's only a small amount of data so this might explain why it doesn’t see any improvement.


Query 3: This is a deeply nested structure, the improvements in the library played a big part in the performance improvement.


Query 4: This query saw a moderate improvement, it is similar to query 3 in it’s structure but it less complex. It spends most of its time in the database, which is probably why it didn’t improve much.


The improvements mostly came from the deeply nested structures, the ones that contained a moderate amount of data but had the complexity of deep nesting. It looks as though the improvement in speed doesn’t come from the amount of data but how nested it is. No matter how you slice it we still saw a 16% improvement in the key areas that we tested as a whole, which for changing two lines is honestly incredible, at least locally.


Now after I had done all this, I worked out that Jason is used by default in Phoenix 1.4, although we can’t use it in our production application so we can still get some of the improvements just not all of them.


I’m always learning something new and with Pluralsight I can have unlimited access to all things programming. But hold on, it’s not just programming. There’s photoshop, visual communication, manufacturing and design. There's a whole bunch! Sign up today and get a free 10-day trial!

Previous
Previous

My first talk

Next
Next

Taking the advice of more experienced developers