JSON0 - Speed Meets Simplicity

JSON0 - Speed Meets Simplicity

JSON and Financial Software System

Recently, software developers needed to make a wise decision on the message format of internal communication between different modules when developing a financial software system. Then, JSON format caught our attention as it has many advantages:

  • It’s self-described and flexible. It could represent any business logic in a clear, transparent, readable way, avoiding the need to spend hours and hours debugging lest we choose some other format (a binary one, especially).
  • It’s easy to convert from FIX format (the format of messages that come from outside to our server) to JSON format.
  • It’s ubiquitous. Any third parties who need to integrate their software into our system could plug in using our communication method, get the messages, and process them right away, saving us from the need to go through hundreds of pages of manuals.
  • It’s easy to produce, parse, and verify JSON format with many online tools. Again, great for third-party integration, as we could independently verify messages and know which side has done something wrong.


Article content
Nowadays, for Financial Information Exchange, the JSON format makes it easy to convert

In short, JSON seems to be a perfect match to our needs. Unfortunately, everything has its downside. JSON format is also well-known for its low performance in producing and consuming compared to other formats. So, before using it, we need to run some simple test scenarios to see if they match our requirements. We focus on producing the side as it would be the main task of our servers.

 Test setup

  • Note: The tests in this article run on an old, ordinary PC running the Linux 2.6 kernel. CPU AMD Ryzen 7 1700 Eight-Core Processor. Therefore, you probably will get much better results on a modern server

  • JVM in these tests starts with option –Xms1500M

For producing JSON objects, we used the JSON-simple library.

The source code is in JSONSimplePerf.java. It’s pretty straightforward.

I use the JSONSimple method to produce JSON objects using the JSON-simple library and convert them to wire format. Note that we change them slightly between the iterator and put them in global memory to prevent compiler optimizations. Parameter size specifies the number of objects that will be produced

In the execute method, we run produceUsingJSONSimple with a size of about 1 million continuously several times (0 means infinite) and print out the elapsed time in between. Note that the first run was with a size of only 1000 to warm up.

The output is in the file JSONSimpleOutput.txt

The source code of the tests and outputs (JSONSimplePerf.java, JSONSimpleOutput.txt) can be found in the link below:

https://github.com/quangnguyenvn/JSON0/tree/main/perf_test/java/server_scripts

JSONSimple test results

We see a pretty stable number of about 3s for producing 1 million JSON objects, which is not bad at all. This performance should be enough for almost all real-life purposes.

However, in our case, we need to send a lot of messages in this format (about 100K/s), so even producing a speed of 3us/object rate could be problematic, not to mention our messages tend to be bigger and more complex than in this sample.

Points of improvement

A quick look at the sample code gives the following idea of optimization

  • The JSON-simple library is Map-based, which means every time you put in an object, a hash function is called upon. It’s a waste in case we only need to produce JSON objects but not get anything out of them (a very typical case, as we often produce or consume messages, not both).
  • The library offers very limited capabilities for reusing JSON objects. While it’s very fast to create objects in modern JVM compared to the earlier versions, it’s still not zero. Furthermore, creating many objects will ultimately trigger GC, something real-time applications don’t like at all.
  • There is no supported method to directly convert from a JSON object to bytes (wire format). Still, we need first to convert it to a String, then use the String getBytes method, which again requires an extra operation of memory allocation and memory copy.

JSON0 approaches

  • We change the library to use JSON0 but keep the above test cases (or keep it as close as possible). The test will produce the same JSON, run the same number of times, etc. Note that we reuse the JSON object using the reset method.
  • And JSON children are created using the createJSON, createJSONArray methods instead of creating a new one. The library also supports the toBytes method to copy the content to a byte array. The run output is in the file JSON0Output.txt

JSON0 test results

We see a stable number of about 1.35s for producing 1 million JSON objects, which is more than double the performance of the json-simple library.

In a nutshell

While it’s rare nowadays, the library helps developers boost performance through software optimizations, without relying on hardware upgrades. Furthermore, the library is easy to use.

Reference & Installation

 Check the JSON0 source code and the usage guidance from the link below:

https://github.com/quangnguyenvn/JSON0

JSON0 is already deployed on the Maven Central Repositories.

Add the dependency below to your pom.xml:

<dependency>
    	<groupId>io.github.kwangng</groupId>
    	<artifactId>JSON0</artifactId>
    	<version>1.0.8</version>
</dependency>        

Example:

  JSON0 json = new JSON0();

  json.reset();
  json.put("Town",  "Hoi An Town");
  json.put("DayLength", 3);
  json.put("Vehicles", "Taxi or Bike");

  JSON0 visits = json.createJSON("MustVisits");
  visits.put("Morning", "Tra Que Vengetable Village");
  visits.put("Afternoon", "The Japanese Bridge");
  visits.put("Evening", "An Bang Beach");

  JSON0 mustTry = json.createJSONArray("MustTries");
  JSON0 foods = mustTry.createJSON("Foods");
  foods.put("Food1", "Banh Mi, Banh Xeo");
  foods.put("Food2", "Com Ga Hoi An");

  JSON0 drinks = mustTry.createJSON("Drinks");
  drinks.put("Drink1", "Cafe Sua Da");
  drinks.put("Drink2", "Mot Hoi An");

Get the element in JSON:

  json.get("MustVisits");

Convert to String:

  json.toString()        

From the example, we can have some guiding steps. Firstly, creating a JSON parent object:

  JSON0 json = new JSON0();        

Building key and value:

 json.put(String key, Object value);        

Getting value:

 json.get(String key);        

Creating a children JSON object:

 json.createJSON(String key);        

Creating an array of children JSON objects:

 json.createJSONArray(String key);        

Reset the JSON object:

 json.reset();        

To view or add a comment, sign in

More articles by Quang Nguyen

Others also viewed

Explore content categories