Saturday, November 19, 2011

Comparison and benchmark of C++ JSON libraries

              I had to select an open source ++ json library for a c++ project. There are quiet a few libraries available with different set of features and selecting one among them is not an easy job. Each one has got it's own pros and cons. Web is full of comparisons and benchmarks of json libraries for javascript, java, python etc. But I couldn't find a good comparison for C++ which could help me to make a decision. So I decided to do a comparison of the available options to see which one fits best for my purpose.
                                                                                                                                                                       
I based my evaluation on following criteria,

1. Features and ease of use
2. Performance
3. Documentation and community support

          As it is not practical to learn and evaluate all the available ones, I decided to try the most popular ones, which are,

1. json-cpp
2. CAJUN
3. json_spirit
4. libjson

1. json-cpp

          Json-cpp is the most popular and widely used json library in c++. It has got a good feature set and nice interface, and is very easy to use. But I couldn't successfully integrate it on a 64-bit machine. I tried to get help on the forum but I didn't get any. Despite its popularity, the community is not very active. A lot of questions remains unanswered on the forum, even after long time. Also there are complaints from users like memory corruption, open critical bugs etc. Since I couldn't integrate it on 64-bit machine and I believe community is crucial for any open source project, I am dropping json-cpp from my further analysis.

2. CAJUN

          Another popular one is Cajun. It's easy to build and integrate, with good interface and features. It comes with a small documentation and a sample program and should not be difficult to get started. But it is not being developed actively  and there has been no release after 2009. Forum is also not active.

3. json_spirit

          Json_spirti is another popular library with a long history. It has got good features and a nice interface. Building and integration was easy. But I noticed the source files take comparatively long time for compilation. It is written using boost spirit parser generator and hence there is a dependency over boost. The source package comes with example programs and one can start right away. This is being actively developed and the support is also good.

4. libjson

          libjson is a super efficient, highly customizable json library with nice features. It provides both C style as well as C++ interface. It comes with some sample programs which would help one to get started in no time. Building and integration was easy. Customization can be done by editing a fully commented header file which should be very easy for any programmer. Another specialty is its well written and comprehensive documentation which is not very common with open source projects. libjson enjoys an active community and forum. The author is fully committed to the project and I was surprised by his quick response to any query in the forum or bug reports.

Performance benchmark

          I wrote a small program to benchmark these libs. I measured the timings for two operations,

1. parsing - Parsing a json string into a library specific json object
2. writing - Converting the library specific json object into a json string

          I have not done any customization of these libraries for extra performance enhancements. I have used an example json string available at www.json.org/example.html as test data. To get accurate results do the same test with your actual json data. I am doing this test on an Ubuntu Linux 64 bit machine with Intel Core i5 2.30 GHZ micro processor.

$ ./JsonBenchmarkCpp > results.dat
$ cat results.dat.
#library                 parsing                  writing                 
cajun                      907                        118                     
json_spirit              8655                      510                     
libjson                    81                          115     

Numbers are the time taken for an operation in micro seconds.
Results
        I used gnuplot to draw a graph out of these numbers. As they say "A picture is worth a thousand words".



I had plot an enlarged graph to see the libjson timings!



      This graph says it all. libjson is the clear winner, followed cajun and json_spirit. libjson can be customized further for higher performance.
Source code and the gnuplot script used for benchmarking can be found at https://github.com/lijoantony/JsonBenchmarkCpp. Feel free to fork away.

Conclusion

          No software is perfect. Good ones undergo continuous evolution. A fully committed author and an active community gives and extra edge for libjson in this aspect. It has performed extremely well in my tests. So libjson is the winner in my analysis. I have chosen libjson for my project. However I would like to thank developers of all the libraries for their time and effort.      


Update: 26-11-2011
              I had built libjson with the default settings for the performance testing. By default libjson would not parse the json string completely and hence my numbers were wrong about libjson. So I did the test again with the proper setting and the post has been updated with the new numbers. Still libjson is at least 10 times faster than other libraries I had tested. Thanks to the libjson author who informed me about this mistake in my test.

Friday, November 18, 2011

JSON vs XML

          Both XML and JSON are competing formats for storage and interchange of data in a machine, language, platform independent way. JSON boasts simplicity as its main advantage over XML. Even though XML is the more established technology, it is being replaced by JSON as the preferred solution in many areas. it's popularity is only growing as more and more developers are choosing JSON over XML as their preferred solution for rpc and data interchange in general. Though JSON had its humble beginning as a simple way of data exchange in java script, currently it's available in all major programming languages and technologies. For any one who would like to learn more about JSON www.json.org would be a good starting point.
         But there is another side to this story. Internet is full of discussions and arguments, where supporters of both have been trying to establish their technical superiority over the other. You can find many blog posts where someone proves one is better than the other. The choice of one over the other is not so straight forward, and it gets complicated due to the fact that the performance of these technologies for any specific purpose depends on the nature of the data as well. So making a decision based on these blog posts might not be good idea.
         So at work, when we had to decide between json and xml for rpc, we did a thorough evaluation of both options in terms of data transfer efficiency and processing efficiency. Json showed clear advantages over xml for our purpose, and we decided to go with JSON. I can't disclose any specifics of the tests, but it should be very easy for any one to do some tests before deciding JSON or XML as the solution for their problem.

Friday, September 23, 2011

How to create a Nautilus extension (aka nautilus plugin)

Nautilus is the default file manager for GNOME. You can textend the functionality of nautilus by writing extensions or plugins.  Extensions can be written in both c and python. This link explains the concepts, documents the API and even has example code snippets.This covers pretty much everything you need to know for writing a nautilus extension in C.  I have tried to add few missing or unclear items here.

1. Icons in context menu and emblem(icon overlay).

When writing a nautilus extension(or plug-gin), you can display your own icon on the context menu, or other menus. You can display you own emblem(also called icon overlay) as well.
What you have to do is to make use of the icon parameter of the corresponding API. For example the nautilus_menu_item_new function which can be used to create a context menu item has following signature in the official doccumentation.

NautilusMenuItem * nautilus_menu_item_new (const char *name,
const char *label,
const char *tip,
const char *icon);

Creates a new menu item that can be added to the toolbar or to a contextual menu.

name : the identifier for the menu item
label : the user-visible label of the menu item
tip : the tooltip of the menu item
icon : the name of the icon to display in the menu item

Returns : a newly create NautilusMenuItem

The last parameter "icon" is the one which we are looking for.
But its type is const char *. So we have to pass the name of the icon while invoking this function. But how to get the icon name?

If you dig a little deeper you will find that there is a thing called "The desktop icon system". The desktop icon system works according to the XDG Icon Theme
Specification at http://www.freedesktop.org/Standards/icon-theme-spec You can use an icon in your code once it is installed in the desktop icon system. So now the question is how to install an icon into the desktop icon theme?

There are some commands available on your desktop which starts with "xdg-" which are tools for various desktop integration operations. The set includes a command for icon management "xdg-icon-resource". You can use this command to install(or uninstall) an icon to the desktop icon system.
For example, to add a 48x48 icon file "name.png" with icon name "name" under the category "emblems" I would execute the command,

sudo xdg-icon-resource install --context emblems --size 48 name.png name

Check the man pages to learn the usage and more about this command.

Once you have added an icon to the desktop icon system you can use the icon name to refer to this icon in your code.

So for our context menu just pass this icon name as the icon parameter of the nautilus_menu_item_new function. The same way you can pass this icon name to other APIs which accepts an icon name.

NOTE:
In the latest GNOME versions, displaying of icons in the context menu is disabled by default. To enable this feature execute the below command.

$ gconftool-2 --type Boolean --set /desktop/gnome/interface/menus_have_icons true

You can check the current value of this param using,

$ gconftool-2 --get /desktop/gnome/interface/menus_have_icon



2. Context menu

The guide talks about adding a context menu item to the main context menu.
But in a similar way you can add sub menus and even create a multi level menu hierarchy. What you have to do is create menu items, create a sub menu, append menu items to sub menu, attach sub menu to a menu item in the parent menu.
Use the following APIs for that,

nautilus_menu_new
nautilus_menu_item_new
nautilus_menu_append_item
nautilus_menu_item_set_submenu

Check the official documentation for details.

3. Resources

You can check projects like RabitVCS to see an actual extension code in action.

These are some resources which describe desktop integration in general.

http://developers.sun.com/solaris/articles/integrating_gnome.html
http://library.gnome.org/admin/system-admin-guide/stable/mimetypes-9.html.en