In terms of ease of use and speed, JSON::SL seems to be a winner:
#!/usr/bin/perl use strict; use warnings; use JSON::SL; my $p = JSON::SL->new; #look for everthing past the first level (ie everything in the array) $p->set_jsonpointer(["/^"]); local $/ = \5; #read only 5 bytes at a time while (my $buf = <DATA>) { $p->feed($buf); #parse what you can #fetch anything that completed the parse and matches the JSON Pointer while (my $obj = $p->fetch) { print "$obj->{Value}{n}: $obj->{Value}{s}\n"; } } __DATA__ [ { "n": 0, "s": "zero" }, { "n": 1, "s": "one" }, { "n": 2, "s": "two" } ]
JSON::Streaming::Reader was fine, but it is slower and suffers from too verbose interface (all of these coderefs are required, although many do nothing):
#!/usr/bin/perl use strict; use warnings; use JSON::Streaming::Reader; my $p = JSON::Streaming::Reader->for_stream(\*DATA); my $obj; my $attr; $p->process_tokens( start_array => sub {}, #who cares? end_array => sub {}, #who cares? end_property => sub {}, #who cares? start_object => sub { $obj = {}; }, #clear the current object start_property => sub { $attr = shift; }, #get the name of the attribute #add the value of the attribute to the object add_string => sub { $obj->{$attr} = shift; }, add_number => sub { $obj->{$attr} = shift; }, #object has finished parsing, it can be used now end_object => sub { print "$obj->{n}: $obj->{s}\n"; }, ); __DATA__ [ { "n": 0, "s": "zero" }, { "n": 1, "s": "one" }, { "n": 2, "s": "two" } ]
It took JSON::SL 2 seconds and JSON::Streaming::Reader 3.6 seconds to analyze 1000 records (note, JSON::SL was filed 4k at a time, I did not control the size of JSON :: Streaming :: Reader).
source share