--- JSON-XS/XS.pm 2007/03/22 17:28:50 1.2 +++ JSON-XS/XS.pm 2007/03/22 21:36:52 1.5 @@ -113,8 +113,8 @@ The mutators for flags all return the JSON object again and thus calls can be chained: - my $json = JSON::XS->new->utf8(1)->pretty(1)->encode ({a => [1,2]}) - => {"a" : [1, 2]} + my $json = JSON::XS->new->utf8(1)->space_after(1)->encode ({a => [1,2]}) + => {"a": [1, 2]} =item $json = $json->ascii ($enable) @@ -126,6 +126,9 @@ If C<$enable> is false, then the C method will not escape Unicode characters unless necessary. + JSON::XS->new->ascii (1)->encode (chr 0x10401) + => \ud801\udc01 + =item $json = $json->utf8 ($enable) If C<$enable> is true, then the C method will encode the JSON @@ -139,12 +142,21 @@ unicode string. Any decoding or encoding (e.g. to UTF-8 or UTF-16) needs to be done yourself, e.g. using the Encode module. -=item $json = $json->pretty ($enabla) +=item $json = $json->pretty ($enable) This enables (or disables) all of the C, C and -C (and in the future possibly more) settings in one call to +C (and in the future possibly more) flags in one call to generate the most readable (or most compact) form possible. + my $json = JSON::XS->new->pretty(1)->encode ({a => [1,2]}) + => + { + "a" : [ + 1, + 2 + ] + } + =item $json = $json->indent ($enable) If C<$enable> is true, then the C method will use a multiline @@ -195,6 +207,18 @@ This setting has no effect when decoding JSON strings. +=item $json = $json->allow_nonref ($enable) + +If C<$enable> is true, then the C method can convert a +non-reference into its corresponding string, number or null JSON value, +which is an extension to RFC4627. Likewise, C will accept those JSON +values instead of croaking. + +If C<$enable> is false, then the C method will croak if it isn't +passed an arrayref or hashref, as JSON strings must either be an object +or array. Likewise, C will croak if given something that is not a +JSON object or array. + =item $json_string = $json->encode ($perl_scalar) Converts the given Perl data structure (a simple scalar or a reference @@ -215,6 +239,143 @@ =back +=head1 COMPARISON + +As already mentioned, this module was created because none of the existing +JSON modules could be made to work correctly. First I will describe the +problems (or pleasures) I encountered with various existing JSON modules, +followed by some benchmark values. JSON::XS was designed not to suffer +from any of these problems or limitations. + +=over 4 + +=item JSON 1.07 + +Slow (but very portable, as it is written in pure Perl). + +Undocumented/buggy Unicode handling (how JSON handles unicode values is +undocumented. One can get far by feeding it unicode strings and doing +en-/decoding oneself, but unicode escapes are not working properly). + +No roundtripping (strings get clobbered if they look like numbers, e.g. +the string C<2.0> will encode to C<2.0> instead of C<"2.0">, and that will +decode into the number 2. + +=item JSON::PC 0.01 + +Very fast. + +Undocumented/buggy Unicode handling. + +No roundtripping. + +Has problems handling many Perl values (e.g. regex results and other magic +values will make it croak). + +Does not even generate valid JSON (C<{1,2}> gets converted to C<{1:2}> +which is not a valid JSON string. + +Unmaintained (maintainer unresponsive for many months, bugs are not +getting fixed). + +=item JSON::Syck 0.21 + +Very buggy (often crashes). + +Very inflexible (no human-readable format supported, format pretty much +undocumented. I need at least a format for easy reading by humans and a +single-line compact format for use in a protocol, and preferably a way to +generate ASCII-only JSON strings). + +Completely broken (and confusingly documented) Unicode handling (unicode +escapes are not working properly, you need to set ImplicitUnicode to +I values on en- and decoding to get symmetric behaviour). + +No roundtripping (simple cases work, but this depends on wether the scalar +value was used in a numeric context or not). + +Dumping hashes may skip hash values depending on iterator state. + +Unmaintained (maintainer unresponsive for many months, bugs are not +getting fixed). + +Does not check input for validity (i.e. will accept non-JSON input and +return "something" instead of raising an exception. This is a security +issue: imagine two banks transfering money between each other using +JSON. One bank might parse a given non-JSON request and deduct money, +while the other might reject the transaction with a syntax error. While a +good protocol will at least recover, that is extra unnecessary work and +the transaction will still not succeed). + +=item JSON::DWIW 0.04 + +Very fast. Very natural. Very nice. + +Undocumented unicode handling (but the best of the pack. Unicode escapes +still don't get parsed properly). + +Very inflexible. + +No roundtripping. + +Does not generate valid JSON (key strings are often unquoted, empty keys +result in nothing being output) + +Does not check input for validity. + +=back + +=head2 SPEED + +It seems that JSON::XS is surprisingly fast, as shown in the following +tables. They have been generated with the help of the C program +in the JSON::XS distribution, to make it easy to compare on your own +system. + +First is a comparison between various modules using a very simple JSON +string, showing the number of encodes/decodes per second (JSON::XS is +the functional interface, while JSON::XS/2 is the OO interface with +pretty-printing and hashkey sorting enabled). + + module | encode | decode | + -----------|------------|------------| + JSON | 14006 | 6820 | + JSON::DWIW | 200937 | 120386 | + JSON::PC | 85065 | 129366 | + JSON::Syck | 59898 | 44232 | + JSON::XS | 1171478 | 342435 | + JSON::XS/2 | 730760 | 328714 | + -----------+------------+------------+ + +That is, JSON::XS is 6 times faster than than JSON::DWIW and about 80 +times faster than JSON, even with pretty-printing and key sorting. + +Using a longer test string (roughly 8KB, generated from Yahoo! Locals +search API (http://nanoref.com/yahooapis/mgPdGg): + + module | encode | decode | + -----------|------------|------------| + JSON | 673 | 38 | + JSON::DWIW | 5271 | 770 | + JSON::PC | 9901 | 2491 | + JSON::Syck | 2360 | 786 | + JSON::XS | 37398 | 3202 | + JSON::XS/2 | 13765 | 3153 | + -----------+------------+------------+ + +Again, JSON::XS leads by far in the encoding case, while still beating +every other module in the decoding case. + +Last example is an almost 8MB large hash with many large binary values +(PNG files), resulting in a lot of escaping: + +=head1 BUGS + +While the goal of this module is to be correct, that unfortunately does +not mean its bug-free, only that I think its design is bug-free. It is +still very young and not well-tested. If you keep reporting bugs they will +be fixed swiftly, though. + =cut 1;