Enums are a way of encoding a set of ordinal values in a type system. That is, they formalise the notion that a value may be one of a small set of specific values. We’ve had them since at least the 1970s. They’re really useful. So why might they not always be the right tool?
I really hate null!
Reflect on that statement. Apparently Tim has a strong dislike for a concept found in lots of programming languages (even brainiac languages like Haskell) and successfully used in millions of programs. He must be crazy I wouldn’t like to have a discussion with him about something contentious like tabs versus spaces.
What is the fastest way to produce JSON output in Java? Well if you have a complicated object tree to turn into JSON I would guess it is probaby Jackson. However, not all JSON output is complicated so maybe we can find quicker and simpler alternatives.
My test class is simple, I call him Thing, he has two fields name and content, he isn’t a Java bean because he doesn’t need to be (maybe your classes don’t need to be Java beans either!), here he is:
We will use JUnitBenchmarks to test my theory that you can be simpler and faster than Jackson. JUnitBenchmarks allows unit tests to be run multiple times and measurements taken, it also allows the code to be warmed up so any JIT compilation should have been carried out before measurements are taken. I’ve set my tests to run a warmup period of 50 iterations followed by 1000 measurement iterations. The Jackson code being tested looks like this:
When tested we get a mean measurement for writing 250 objects using Jackson of 0.95 seconds
json-lib is usually a worse performer than Jackson. Here is the equivalent code using json-lib:
When tested we get a mean measurement for writing 250 objects using json-lib of 10.74 seconds. Not so good!
Who needs library code? Maybe that new fangled String.format will be quicker and simpler. Here is the code:
When tested we get a mean measurement for writing 250 objects using String.format of 5.26 seconds. Better than json-lib but Jackson isn’t looking worried!
I guess that format string must be expensive to parse so lets try a StringBuilder. Here is the code:
When tested we get a mean measurement for writing 250 objects using StringBuilder of 0.91 seconds. Finally a winner, faster than Jackson but you had better quote those strings properly!
People have always told me that StringBuilder is unsyncronised so should be faster than an old fashioned StringBuffer so lets check. Here is the code:
When tested we get a mean measurement for writing 250 objects using StringBuffer of 0.60 seconds. Hang on! That is the fastest yet! What is going on?
What is going on is that I have been playing fast and loose with statistics by only presenting the mean times in seconds for each benchmark. By extracting the raw data and applying the power of statistics (well I looked at the distributions and standard deviations) it turns out you cannot tell the difference between the StringBuilder and the StringBuffer, so all is well, and String[Builder|Buffer] are both winners! Jackson is also a winner since for more complex object trees it will allow you to write more maintainable code than using a StringBuilder combined with loops and conditional logic and is almost as fast as a StringBuilder (or StringBuffer).
So what have we learnt? Firstly, use Jackson if you have to serialise your objects into JSON. Secondly, JUnitBenchmarks is a very handy library. Thirdly, if you don’t present a standard deviation with your benchmark results then your results may not mean what you think they mean.
You are currently browsing the archives for the Java category.