Comparison to Other Libraries

There exist many C++ JSON libraries, but two are particularly noteworthy for the purpose of comparison: RapidJSON, JSON for Modern C++ (referred to herein as nlohmann’s JSON, or nlohmann), and SIMD JSON.

Comparison to nlohmann JSON

Value Type: nlohmann::basic_json

template<
  template<typename, typename, typename...> class ObjectType,
  template<typename, typename...> class ArrayType,
  class StringType,
  class BooleanType,
  class NumberIntegerType,
  class NumberUnsignedType,
  class NumberFloatType,
  template<typename> class AllocatorType,
  template<typename, typename = void> class JSONSerializer
  >
class basic_json
{
private:
  ....
  friend ::nlohmann::detail::parser<basic_json>;
  friend ::nlohmann::detail::serializer<basic_json>;
...

This library adopts a "kitchen sink" approach. It contains a wealth of features, even those with niche uses. Its weakness is that the many template parameters, while allowing for configurability, inhibit the best possible optimizations. The consequence is that the library performs poorly. The ability to configure every aspect of the value type has the paradoxical effect of making it less suitable as a vocabulary type.

  • basic_json is a class template. Libraries must agree on the choices of template parameters to be interoperable.

  • Too much customization. We struggle to see a use case for making BooleanType anything other than bool.

  • Poor separation of concerns. The basic_json container declaration needlessly conflates parsing and serialization APIs.

  • Limited allocator support. Only stateless allocators are allowed, which rules out the most important type of allocator, a local arena-based implementation.

  • No incremental parsing, no incremental serialization.

  • Slow parsing and serialization performance.

  • Full-featured, including JSON Pointer, CBOR, and others.

Comparison to RapidJSON

template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
class GenericValue;

template <bool Const, typename ValueT>
class GenericArray;

template <bool Const, typename ValueT>
class GenericObject;
  • The value type is not regular. Assignment is destructive, performing a = b is equivalent to a = std::move(b). No copy construction or copy assignment allowed.

  • Object types have no hash table or index to reduce the cost of lookups.

  • Allocators have reference semantics. Problems with lifetime are easily encountered.

  • The interface of the array and object types are considerably different from their standard library equivalents, and not idiomatic.

  • No incremental parsing, no incremental serialization.

  • Parsing and serialization performance is better than most other libraries.

Comparison to SIMD JSON

class ParsedJson;

This is quite an interesting data structure, which is optimized to work well with the SIMD parser. It makes very good design choices for the intended use-case. However it is not well suited as a vocabulary type due to the necessary limitations.

  • Sequential access only, via ParsedJson::BasicIterator

  • Read-only, can only be populated by the provided SIMD JSON parser.

  • The fastest available JSON parser.