Thursday, December 29, 2011

LuaJSON 1.3 Released

LuaJSON 1.3 is released to the wild!
Major changes made:
  • new 'nothrow' global option - currently a trivial 'pcall' hook on decode, but could later resolve to a more efficient handler
  • enhanced error output from the 'next' branch
  • hopefully "stackless" parser - limit of parsing depth now as large as heap and not stack

Rockspec for those using LuaRocks if it hasn't hit their repo yet: https://raw.github.com/harningt/luajson/b7cb1e6221ae6b70b208b242c1654da39087230d/rockspecs/luajson-1.3-1.rockspec
GitHub link for signed tag: https://github.com/harningt/luajson/tree/1.3
Release download tarball: https://github.com/downloads/harningt/luajson/luajson-1.3.tar.gz

The "stackless" parser is basically a linearization of the LPeg parser so that it parses JSON tokens and passes them into a stack/state-machine implemented as a Lua state object. This degrades performance slightly in the pre 1.2.1 era, but removes C/LPeg stack depth problems encountered in all prior implementations (including the abominably slow 1.2.2 version that reduced the problem, but didn't solve it).

While profiling performance, I found that some unrolling versions seemed to be a wee bit faster, but used more memory and had more pagefaults. My focus on future releases of LuaJSON will be on speed, including a possibility of 2.0 release breaking compatibility in the interest of getting > 2 MB/s JSON parsing performance. Looking at the strict YAJL parser - it hits >100 MB/s on the same data where I get 2 MB/s at best. If I can pull in an MIT-like-licensed C-based JSON parser into Lua and get >= 10x performance, I may add an option for the parser to try to consume the other parser under the LuaJSON interface (for uniformity).

Later I plan on enhancing encoding performance, but for the time being, decoding is most important right now.