package Bencher::Scenario::Serializers;

our $DATE = '2016-01-20'; # DATE
our $VERSION = '0.10'; # VERSION

use 5.010001;
use strict;
use utf8;
use warnings;

our $scenario = {
    summary => 'Benchmark Perl data serialization modules',
    participants => [
        {
            tags => ['json', 'serialize'],
            module => 'JSON::PP',
            function => 'encode_json',
            code_template => 'state $json = JSON::PP->new->allow_nonref; $json->encode(<data>)',
        },
        {
            tags => ['json', 'deserialize'],
            module => 'JSON::PP',
            function => 'decode_json',
            code_template => 'state $json = JSON::PP->new->allow_nonref; $json->decode(<data>)',
        },
        {
            tags => ['json', 'serialize'],
            module => 'JSON::XS',
            function => 'encode_json',
            code_template => 'state $json = JSON::XS->new->allow_nonref; $json->encode(<data>)',
        },
        {
            tags => ['json', 'deserialize'],
            module => 'JSON::XS',
            function => 'decode_json',
            code_template => 'state $json = JSON::XS->new->allow_nonref; $json->decode(<data>)',
        },
        {
            tags => ['json', 'serialize'],
            module => 'Cpanel::JSON::XS',
            function => 'encode_json',
            code_template => 'state $json = Cpanel::JSON::XS->new->allow_nonref; $json->encode(<data>)',
        },
        {
            tags => ['json', 'deserialize'],
            module => 'Cpanel::JSON::XS',
            function => 'decode_json',
            code_template => 'state $json = Cpanel::JSON::XS->new->allow_nonref; $json->decode(<data>)',
        },
        {
            tags => ['json', 'serialize'],
            module => 'JSON::MaybeXS',
            function => 'encode_json',
            code_template => 'state $json = JSON::MaybeXS->new(allow_nonref=>1); $json->encode(<data>)',
        },
        {
            tags => ['json', 'deserialize'],
            module => 'JSON::MaybeXS',
            function => 'decode_json',
            code_template => 'state $json = JSON::MaybeXS->new(allow_nonref=>1); $json->decode(<data>)',
        },
        {
            tags => ['json', 'deserialize'],
            fcall_template => 'JSON::Decode::Regexp::from_json(<data>)',
        },
        {
            tags => ['json', 'deserialize', 'cant_handle_scalar'],
            fcall_template => 'JSON::Decode::Marpa::from_json(<data>)',
        },
        {
            name => 'Pegex::JSON',
            tags => ['json', 'deserialize'],
            module => 'Pegex::JSON',
            code_template => 'state $obj = Pegex::JSON->new; $obj->load(<data>);',
        },
        {
            tags => ['json', 'serialize'],
            fcall_template => 'JSON::Create::create_json(<data>)',
        },
        {
            tags => ['json', 'deserialize'],
            fcall_template => 'JSON::Parse::parse_json(<data>)',
        },

        {
            tags => ['yaml', 'serialize'],
            fcall_template => 'YAML::Old::Dump(<data>)',
        },
        {
            tags => ['yaml', 'deserialize'],
            fcall_template => 'YAML::Old::Load(<data>)',
        },
        {
            tags => ['yaml', 'serialize'],
            fcall_template => 'YAML::Syck::Dump(<data>)',
        },
        {
            tags => ['yaml', 'deserialize'],
            fcall_template => 'YAML::Syck::Load(<data>)',
        },
        {
            tags => ['yaml', 'serialize'],
            fcall_template => 'YAML::XS::Dump(<data>)',
        },
        {
            tags => ['yaml', 'deserialize'],
            fcall_template => 'YAML::XS::Load(<data>)',
        },

        {
            tags => ['binary', 'serialize', 'cant_handle_scalar'],
            fcall_template => 'Storable::freeze(<data>)',
        },
        {
            tags => ['binary', 'deserialize', 'cant_handle_scalar'],
            fcall_template => 'Storable::thaw(<data>)',
        },

        {
            tags => ['binary', 'serialize'],
            fcall_template => 'Sereal::encode_sereal(<data>)',
        },
        {
            tags => ['binary', 'deserialize'],
            fcall_template => 'Sereal::decode_sereal(<data>)',
        },

        {
            name => 'Data::MessagePack::pack',
            tags => ['binary', 'serialize'],
            module => 'Data::MessagePack',
            function => 'pack',
            code_template => 'state $obj = Data::MessagePack->new; $obj->pack(<data>)',
        },
        {
            name => 'Data::MessagePack::unpack',
            tags => ['binary', 'deserialize'],
            module => 'Data::MessagePack',
            function => 'unpack',
            code_template => 'state $obj = Data::MessagePack->new; $obj->unpack(<data>)',
        },
    ],

    # XXX: add more datasets (larger data, etc)
    datasets => [
        {
            name => 'undef',
            summary => 'undef',
            args => {data=>undef},
            tags => ['serialize'],
            include_participant_tags => ['serialize'],
            exclude_participant_tags => ['cant_handle_scalar'],
        },
        {
            name => 'num',
            summary => 'A single number (-1.23)',
            args => {data=>-1.23},
            tags => ['serialize'],
            include_participant_tags => ['serialize'],
            exclude_participant_tags => ['cant_handle_scalar'],
        },
        {
            name => 'str1k',
            summary => 'A non-Unicode string 1024 characters/bytes long',
            args => {data=>'a' x 1024},
            tags => ['serialize'],
            include_participant_tags => ['serialize'],
            exclude_participant_tags => ['cant_handle_scalar'],
        },
        {
            name => 'str1k',
            summary => 'A Unicode string 1024 characters (3072-bytes) long',
            args => {data=>'我爱你爱你一辈子' x 128},
            tags => ['serialize', 'unicode'],
            include_participant_tags => ['serialize'],
            exclude_participant_tags => ['cant_handle_scalar'],
        },

        {
            name => 'array_int_10',
            summary => 'A 10-element array containing ints',
            args => {data=>[1..10]},
            tags => ['serialize'],
            include_participant_tags => ['serialize'],
        },
        {
            name => 'array_int_100',
            summary => 'A 100-element array containing ints',
            args => {data=>[1..100]},
            tags => ['serialize'],
            include_participant_tags => ['serialize'],
        },
        {
            name => 'array_int_1000',
            summary => 'A 1000-element array containing ints',
            args => {data=>[1..1000]},
            tags => ['serialize'],
            include_participant_tags => ['serialize'],
        },
        {
            name => 'array_str1k_10',
            summary => 'A 10-element array containing 1024-characters/bytes-long non-Unicode strings',
            args => {data=>[('a' x 1024) x 10]},
            tags => ['serialize'],
            include_participant_tags => ['serialize'],
        },
        {
            name => 'array_ustr1k_10',
            summary => 'A 10-element array containing 1024-characters-long (3072-bytes long) Unicode strings',
            args => {data=>[('我爱你爱你一辈子' x 128) x 10]},
            tags => ['serialize', 'json'],
            include_participant_tags => ['serialize'],
        },

        {
            name => 'hash_int_10',
            summary => 'A 10-key hash {1=>0, ..., 10=>0}',
            args => {data=>{map {$_=>0} 1..10}},
            tags => ['serialize'],
            include_participant_tags => ['serialize'],
        },
        {
            name => 'hash_int_100',
            summary => 'A 100-key hash {1=>0, ..., 100=>0}',
            args => {data=>{map {$_=>0} 1..100}},
            tags => ['serialize'],
            include_participant_tags => ['serialize'],
        },
        {
            name => 'hash_int_1000',
            summary => 'A 1000-key hash {1=>0, ..., 1000=>0}',
            args => {data=>{map {$_=>0} 1..1000}},
            tags => ['serialize'],
            include_participant_tags => ['serialize'],
        },

        {
            name => 'json:null',
            summary => 'null',
            args => {data=>'null'},
            tags => ['deserialize'],
            include_participant_tags => ['json & deserialize'],
            exclude_participant_tags => ['cant_handle_scalar'],
        },
        {
            name => 'json:num',
            summary => 'A single number (-1.23)',
            args => {data=>-1.23},
            tags => ['deserialize'],
            include_participant_tags => ['json & deserialize'],
            exclude_participant_tags => ['cant_handle_scalar'],
        },
        {
            name => 'json:str1k',
            summary => 'A non-Unicode (ASCII) string 1024-characters/bytes long',
            args => {data=>'"' . ('a' x 1024) . '"'},
            tags => ['deserialize'],
            include_participant_tags => ['json & deserialize'],
            exclude_participant_tags => ['cant_handle_scalar'],
        },

        {
            name => 'json:array_int_10',
            summary => 'A 10-element array containing ints',
            args => {data=>'['.join(',',1..10).']'},
            tags => ['deserialize'],
            include_participant_tags => ['json & deserialize'],
        },
        {
            name => 'json:array_int_100',
            summary => 'A 10-element array containing ints',
            args => {data=>'['.join(',',1..100).']'},
            tags => ['deserialize'],
            include_participant_tags => ['json & deserialize'],
        },
        {
            name => 'json:array_int_1000',
            summary => 'A 1000-element array containing ints',
            args => {data=>'['.join(',',1..1000).']'},
            tags => ['deserialize'],
            include_participant_tags => ['json & deserialize'],
        },
        {
            name => 'json:array_str1k_10',
            summary => 'A 10-element array containing 1024-characters/bytes-long non-Unicode strings',
            args => {data=>'['.join(',',(('"'.('a' x 1024).'"') x 10)).']'},
            tags => ['deserialize'],
            include_participant_tags => ['json & deserialize'],
        },

        {
            name => 'json:hash_int_10',
            summary => 'A 10-key hash {"1":0, ..., "10":0}',
            args => {data=>'{'.join(',', map {qq("$_":0)} 1..10).'}'},
            tags => ['deserialize'],
            include_participant_tags => ['json & deserialize'],
        },
        {
            name => 'json:hash_int_100',
            summary => 'A 100-key hash {"1":0, ..., "100":0}',
            args => {data=>'{'.join(',', map {qq("$_":0)} 1..100).'}'},
            tags => ['deserialize'],
            include_participant_tags => ['json & deserialize'],
        },
        {
            name => 'json:hash_int_1000',
            summary => 'A 1000-key hash {"1":0, ..., "1000":0}',
            args => {data=>'{'.join(',', map {qq("$_":0)} 1..1000).'}'},
            tags => ['deserialize'],
            include_participant_tags => ['json & deserialize'],
        },
    ],
};

1;
# ABSTRACT: Benchmark Perl data serialization modules

__END__

=pod

=encoding UTF-8

=head1 NAME

Bencher::Scenario::Serializers - Benchmark Perl data serialization modules

=head1 VERSION

This document describes version 0.10 of Bencher::Scenario::Serializers (from Perl distribution Bencher-Scenario-Serializers), released on 2016-01-20.

=head1 SYNOPSIS

To run benchmark with default option:

 % bencher -m Serializers

To run module startup overhead benchmark:

 % bencher --module-startup -m Serializers

For more options (dump scenario, list/include/exclude/add participants, list/include/exclude/add datasets, etc), see L<bencher> or run C<bencher --help>.

=head1 BENCHMARKED MODULES

L<JSON::PP> 2.27300

L<JSON::XS> 3.01

L<Cpanel::JSON::XS> 3.0210

L<JSON::MaybeXS> 1.003005

L<JSON::Decode::Regexp> 0.03

L<JSON::Decode::Marpa> 0.02

L<Pegex::JSON> 0.27

L<JSON::Create> 0.14

L<JSON::Parse> 0.39

L<YAML::Old> 1.07

L<YAML::Syck> 1.29

L<YAML::XS> 0.59

L<Storable> 2.53

L<Sereal> 3.014

L<Data::MessagePack> 0.49

=head1 BENCHMARK PARTICIPANTS

=over

=item * JSON::PP::encode_json (perl_code) []

Code template:

 state $json = JSON::PP->new->allow_nonref; $json->encode(<data>)



=item * JSON::PP::decode_json (perl_code) []

Code template:

 state $json = JSON::PP->new->allow_nonref; $json->decode(<data>)



=item * JSON::XS::encode_json (perl_code) []

Code template:

 state $json = JSON::XS->new->allow_nonref; $json->encode(<data>)



=item * JSON::XS::decode_json (perl_code) []

Code template:

 state $json = JSON::XS->new->allow_nonref; $json->decode(<data>)



=item * Cpanel::JSON::XS::encode_json (perl_code) []

Code template:

 state $json = Cpanel::JSON::XS->new->allow_nonref; $json->encode(<data>)



=item * Cpanel::JSON::XS::decode_json (perl_code) []

Code template:

 state $json = Cpanel::JSON::XS->new->allow_nonref; $json->decode(<data>)



=item * JSON::MaybeXS::encode_json (perl_code) []

Code template:

 state $json = JSON::MaybeXS->new(allow_nonref=>1); $json->encode(<data>)



=item * JSON::MaybeXS::decode_json (perl_code) []

Code template:

 state $json = JSON::MaybeXS->new(allow_nonref=>1); $json->decode(<data>)



=item * JSON::Decode::Regexp::from_json (perl_code) []

Function call template:

 JSON::Decode::Regexp::from_json(<data>)



=item * JSON::Decode::Marpa::from_json (perl_code) []

Function call template:

 JSON::Decode::Marpa::from_json(<data>)



=item * Pegex::JSON (perl_code) []

Code template:

 state $obj = Pegex::JSON->new; $obj->load(<data>);



=item * JSON::Create::create_json (perl_code) []

Function call template:

 JSON::Create::create_json(<data>)



=item * JSON::Parse::parse_json (perl_code) []

Function call template:

 JSON::Parse::parse_json(<data>)



=item * YAML::Old::Dump (perl_code) []

Function call template:

 YAML::Old::Dump(<data>)



=item * YAML::Old::Load (perl_code) []

Function call template:

 YAML::Old::Load(<data>)



=item * YAML::Syck::Dump (perl_code) []

Function call template:

 YAML::Syck::Dump(<data>)



=item * YAML::Syck::Load (perl_code) []

Function call template:

 YAML::Syck::Load(<data>)



=item * YAML::XS::Dump (perl_code) []

Function call template:

 YAML::XS::Dump(<data>)



=item * YAML::XS::Load (perl_code) []

Function call template:

 YAML::XS::Load(<data>)



=item * Storable::freeze (perl_code) []

Function call template:

 Storable::freeze(<data>)



=item * Storable::thaw (perl_code) []

Function call template:

 Storable::thaw(<data>)



=item * Sereal::encode_sereal (perl_code) []

Function call template:

 Sereal::encode_sereal(<data>)



=item * Sereal::decode_sereal (perl_code) []

Function call template:

 Sereal::decode_sereal(<data>)



=item * Data::MessagePack::pack (perl_code) []

Code template:

 state $obj = Data::MessagePack->new; $obj->pack(<data>)



=item * Data::MessagePack::unpack (perl_code) []

Code template:

 state $obj = Data::MessagePack->new; $obj->unpack(<data>)



=back

=head1 BENCHMARK DATASETS

=over

=item * undef [serialize]

undef

=item * num [serialize]

A single number (-1.23)

=item * str1k [serialize]

A non-Unicode string 1024 characters/bytes long

=item * str1k [serialize, unicode]

A Unicode string 1024 characters (3072-bytes) long

=item * array_int_10 [serialize]

A 10-element array containing ints

=item * array_int_100 [serialize]

A 100-element array containing ints

=item * array_int_1000 [serialize]

A 1000-element array containing ints

=item * array_str1k_10 [serialize]

A 10-element array containing 1024-characters/bytes-long non-Unicode strings

=item * array_ustr1k_10 [serialize, json]

A 10-element array containing 1024-characters-long (3072-bytes long) Unicode strings

=item * hash_int_10 [serialize]

A 10-key hash {1=>0, ..., 10=>0}

=item * hash_int_100 [serialize]

A 100-key hash {1=>0, ..., 100=>0}

=item * hash_int_1000 [serialize]

A 1000-key hash {1=>0, ..., 1000=>0}

=item * json:null [deserialize]

null

=item * json:num [deserialize]

A single number (-1.23)

=item * json:str1k [deserialize]

A non-Unicode (ASCII) string 1024-characters/bytes long

=item * json:array_int_10 [deserialize]

A 10-element array containing ints

=item * json:array_int_100 [deserialize]

A 10-element array containing ints

=item * json:array_int_1000 [deserialize]

A 1000-element array containing ints

=item * json:array_str1k_10 [deserialize]

A 10-element array containing 1024-characters/bytes-long non-Unicode strings

=item * json:hash_int_10 [deserialize]

A 10-key hash {"1":0, ..., "10":0}

=item * json:hash_int_100 [deserialize]

A 100-key hash {"1":0, ..., "100":0}

=item * json:hash_int_1000 [deserialize]

A 1000-key hash {"1":0, ..., "1000":0}

=back

=head1 SAMPLE BENCHMARK RESULTS

Run on: perl: I<< v5.22.0 >>, CPU: I<< Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz (4 cores) >>, OS: I<< GNU/Linux Debian version 8.0 >>, OS kernel: I<< Linux version 3.16.0-4-amd64 >>.

Benchmark serializing (C<< bencher -m Serializers --include-participant-tags-json '["serialize"]' >>):

 +-------------------------------+-----------------+-------------+-------------+---------+---------+
 | participant                   | dataset         | rate (/s)   | time (ms)   | errors  | samples |
 +-------------------------------+-----------------+-------------+-------------+---------+---------+
 | YAML::Old::Dump               | hash_int_1000   | 24.8        | 40.3        | 5.6e-05 | 20      |
 | YAML::Old::Dump               | array_int_1000  | 33          | 30.3        | 2.2e-05 | 20      |
 | JSON::PP::encode_json         | hash_int_1000   | 229         | 4.37        | 4.4e-06 | 21      |
 | YAML::Old::Dump               | hash_int_100    | 246         | 4.07        | 2.2e-06 | 20      |
 | YAML::Old::Dump               | array_int_100   | 321         | 3.12        | 2e-06   | 20      |
 | JSON::PP::encode_json         | array_int_1000  | 601         | 1.66        | 2.5e-06 | 22      |
 | YAML::Syck::Dump              | hash_int_1000   | 6.6e+02     | 1.5         | 1.1e-05 | 21      |
 | YAML::XS::Dump                | hash_int_1000   | 700         | 1.43        | 1.1e-06 | 20      |
 | YAML::Old::Dump               | array_ustr1k_10 | 876         | 1.14        | 4.3e-07 | 20      |
 | YAML::Syck::Dump              | array_int_1000  | 1.67e+03    | 0.598       | 4.8e-07 | 20      |
 | YAML::XS::Dump                | array_int_1000  | 1.75e+03    | 0.572       | 4.3e-07 | 20      |
 | JSON::PP::encode_json         | array_ustr1k_10 | 1.89e+03    | 0.529       | 8.1e-07 | 25      |
 | YAML::Old::Dump               | hash_int_10     | 2.05e+03    | 0.488       | 4.3e-07 | 20      |
 | YAML::Old::Dump               | array_str1k_10  | 2.07e+03    | 0.484       | 2.1e-07 | 20      |
 | JSON::PP::encode_json         | hash_int_100    | 2.24e+03    | 0.447       | 4.3e-07 | 20      |
 | YAML::Old::Dump               | array_int_10    | 2.61e+03    | 0.383       | 1.1e-06 | 21      |
 | YAML::XS::Dump                | array_ustr1k_10 | 3052        | 0.3276      | 5.3e-08 | 20      |
 | Cpanel::JSON::XS::encode_json | array_ustr1k_10 | 3.4e+03     | 0.294       | 2.1e-07 | 20      |
 | JSON::XS::encode_json         | array_ustr1k_10 | 3.55e+03    | 0.281       | 2.1e-07 | 20      |
 | JSON::MaybeXS::encode_json    | array_ustr1k_10 | 3615.89     | 0.276557    | 0       | 22      |
 | Sereal::encode_sereal         | hash_int_1000   | 3.7e+03     | 0.27        | 2.1e-07 | 20      |
 | Data::MessagePack::pack       | hash_int_1000   | 4.31e+03    | 0.232       | 2.1e-07 | 20      |
 | Storable::freeze              | hash_int_1000   | 4.4e+03     | 0.23        | 1.1e-06 | 21      |
 | JSON::MaybeXS::encode_json    | hash_int_1000   | 4858.164    | 0.2058391   | 1.2e-11 | 20      |
 | Cpanel::JSON::XS::encode_json | hash_int_1000   | 4.88e+03    | 0.205       | 2.1e-07 | 20      |
 | JSON::XS::encode_json         | hash_int_1000   | 4.92e+03    | 0.203       | 2.7e-07 | 20      |
 | JSON::Create::create_json     | hash_int_1000   | 5.09e+03    | 0.196       | 2.1e-07 | 20      |
 | JSON::PP::encode_json         | array_int_100   | 5.83e+03    | 0.171       | 1.6e-07 | 20      |
 | YAML::Old::Dump               | str1k           | 7e+03       | 0.14        | 4.8e-07 | 20      |
 | YAML::Syck::Dump              | array_ustr1k_10 | 6.96e+03    | 0.144       | 2.1e-07 | 20      |
 | YAML::Syck::Dump              | hash_int_100    | 6.99e+03    | 0.143       | 2.1e-07 | 20      |
 | YAML::XS::Dump                | hash_int_100    | 7.22e+03    | 0.139       | 2.1e-07 | 21      |
 | YAML::XS::Dump                | array_str1k_10  | 7.26e+03    | 0.138       | 2.1e-07 | 21      |
 | JSON::PP::encode_json         | array_str1k_10  | 1.05e+04    | 0.0949      | 2.4e-07 | 20      |
 | YAML::Old::Dump               | str1k           | 1.27e+04    | 0.0787      | 7.8e-08 | 21      |
 | YAML::Old::Dump               | num             | 1.3e+04     | 0.075       | 3.4e-07 | 21      |
 | Storable::freeze              | array_int_1000  | 1.42e+04    | 0.0705      | 1.2e-07 | 24      |
 | JSON::Create::create_json     | array_ustr1k_10 | 1.43e+04    | 0.0701      | 2.3e-08 | 27      |
 | YAML::Old::Dump               | undef           | 1.54e+04    | 0.065       | 8e-08   | 20      |
 | YAML::Syck::Dump              | array_int_100   | 1.6e+04     | 0.062       | 3.1e-07 | 21      |
 | YAML::XS::Dump                | array_int_100   | 1.63e+04    | 0.0613      | 2.3e-08 | 26      |
 | JSON::PP::encode_json         | str1k           | 1.82e+04    | 0.0549      | 2.5e-08 | 22      |
 | JSON::PP::encode_json         | hash_int_10     | 1.93e+04    | 0.0519      | 2.7e-08 | 20      |
 | YAML::Syck::Dump              | array_str1k_10  | 19449.4     | 0.0514155   | 0       | 20      |
 | Cpanel::JSON::XS::encode_json | array_int_1000  | 2.04e+04    | 0.0491      | 5.3e-08 | 20      |
 | JSON::MaybeXS::encode_json    | array_int_1000  | 2.073e+04   | 0.04823     | 1.3e-08 | 20      |
 | JSON::XS::encode_json         | array_int_1000  | 2.1e+04     | 0.048       | 2.6e-07 | 21      |
 | Cpanel::JSON::XS::encode_json | str1k           | 22207.2     | 0.0450304   | 1e-10   | 22      |
 | JSON::MaybeXS::encode_json    | str1k           | 2.2e+04     | 0.045       | 1.7e-07 | 21      |
 | JSON::Create::create_json     | array_int_1000  | 2.32e+04    | 0.0431      | 4e-08   | 20      |
 | JSON::XS::encode_json         | str1k           | 2.35e+04    | 0.0425      | 9.8e-08 | 30      |
 | Data::MessagePack::pack       | array_int_1000  | 2.68e+04    | 0.0373      | 1.2e-08 | 24      |
 | YAML::XS::Dump                | str1k           | 2.78e+04    | 0.0359      | 1.3e-08 | 20      |
 | Sereal::encode_sereal         | array_int_1000  | 2.82e+04    | 0.0355      | 1.2e-08 | 26      |
 | JSON::Create::create_json     | array_str1k_10  | 40353.4     | 0.0247811   | 1.2e-11 | 20      |
 | Storable::freeze              | hash_int_100    | 4.2e+04     | 0.0238      | 2.5e-08 | 23      |
 | Sereal::encode_sereal         | hash_int_100    | 4.3e+04     | 0.023       | 7.7e-08 | 25      |
 | JSON::MaybeXS::encode_json    | array_str1k_10  | 4.41e+04    | 0.0227      | 2.7e-08 | 20      |
 | JSON::PP::encode_json         | array_int_10    | 4.4e+04     | 0.023       | 1.1e-07 | 20      |
 | Cpanel::JSON::XS::encode_json | array_str1k_10  | 4.51e+04    | 0.0222      | 2.7e-08 | 20      |
 | JSON::XS::encode_json         | array_str1k_10  | 4.65e+04    | 0.0215      | 2.3e-08 | 26      |
 | Data::MessagePack::pack       | hash_int_100    | 4.66e+04    | 0.0214      | 2.7e-08 | 20      |
 | YAML::Syck::Dump              | hash_int_10     | 5.17e+04    | 0.0193      | 2.5e-08 | 23      |
 | YAML::Syck::Dump              | str1k           | 5.44e+04    | 0.0184      | 6.5e-09 | 21      |
 | Cpanel::JSON::XS::encode_json | hash_int_100    | 5.53e+04    | 0.0181      | 3.3e-08 | 20      |
 | JSON::MaybeXS::encode_json    | hash_int_100    | 5.61e+04    | 0.0178      | 5.1e-08 | 22      |
 | JSON::XS::encode_json         | hash_int_100    | 5.83e+04    | 0.0171      | 2.7e-08 | 20      |
 | YAML::XS::Dump                | hash_int_10     | 6.08e+04    | 0.0164      | 6.7e-09 | 20      |
 | JSON::Create::create_json     | hash_int_100    | 6.1e+04     | 0.016       | 8.5e-08 | 21      |
 | YAML::XS::Dump                | str1k           | 6.3e+04     | 0.016       | 8.7e-08 | 20      |
 | YAML::Syck::Dump              | array_int_10    | 8.4e+04     | 0.012       | 6.7e-08 | 20      |
 | JSON::PP::encode_json         | str1k           | 8.989e+04   | 0.01112     | 3.1e-09 | 23      |
 | YAML::Syck::Dump              | str1k           | 1.04e+05    | 0.00965     | 3.3e-09 | 20      |
 | Storable::freeze              | array_int_100   | 104867      | 0.00953588  | 0       | 20      |
 | YAML::XS::Dump                | array_int_10    | 1.1e+05     | 0.0093      | 4.3e-08 | 20      |
 | Storable::freeze              | array_ustr1k_10 | 1.27e+05    | 0.0079      | 1.7e-08 | 20      |
 | Storable::freeze              | hash_int_10     | 1.39e+05    | 0.00719     | 3.3e-09 | 21      |
 | JSON::Create::create_json     | str1k           | 142290      | 0.00702789  | 1.1e-11 | 20      |
 | YAML::Syck::Dump              | num             | 1.4249e+05  | 0.0070181   | 1.5e-10 | 31      |
 | Storable::freeze              | array_str1k_10  | 1.729e+05   | 0.005784    | 1.7e-09 | 20      |
 | YAML::Syck::Dump              | undef           | 1.79e+05    | 0.00557     | 6.7e-09 | 20      |
 | Cpanel::JSON::XS::encode_json | array_int_100   | 1.8e+05     | 0.0055      | 2.2e-08 | 20      |
 | JSON::MaybeXS::encode_json    | array_int_100   | 1.86e+05    | 0.00537     | 6.7e-09 | 20      |
 | JSON::XS::encode_json         | array_int_100   | 1.89e+05    | 0.0053      | 5e-09   | 20      |
 | JSON::PP::encode_json         | num             | 1.92e+05    | 0.00521     | 6.7e-09 | 20      |
 | YAML::XS::Dump                | num             | 2.13e+05    | 0.0047      | 1.7e-09 | 20      |
 | Storable::freeze              | array_int_10    | 2.27e+05    | 0.0044      | 6.5e-09 | 21      |
 | Data::MessagePack::pack       | array_int_100   | 2.39e+05    | 0.00419     | 1.4e-09 | 29      |
 | JSON::Create::create_json     | array_int_100   | 2.4e+05     | 0.0042      | 2.2e-08 | 20      |
 | Sereal::encode_sereal         | array_int_100   | 2.43e+05    | 0.00411     | 6.7e-09 | 20      |
 | Sereal::encode_sereal         | array_ustr1k_10 | 2.89e+05    | 0.00346     | 6.7e-09 | 20      |
 | JSON::PP::encode_json         | undef           | 2.98e+05    | 0.00335     | 1.7e-09 | 20      |
 | Data::MessagePack::pack       | array_ustr1k_10 | 3.18e+05    | 0.00314     | 6.5e-09 | 21      |
 | Sereal::encode_sereal         | array_str1k_10  | 3.741e+05   | 0.002673    | 8.3e-10 | 20      |
 | JSON::Create::create_json     | str1k           | 3.8e+05     | 0.0026      | 1.4e-08 | 27      |
 | Data::MessagePack::pack       | array_str1k_10  | 3.87e+05    | 0.00258     | 2.5e-09 | 20      |
 | YAML::XS::Dump                | undef           | 3.9e+05     | 0.00257     | 6.7e-09 | 20      |
 | Sereal::encode_sereal         | hash_int_10     | 3.91e+05    | 0.00255     | 3e-09   | 25      |
 | JSON::MaybeXS::encode_json    | str1k           | 4e+05       | 0.0025      | 3.3e-09 | 20      |
 | Cpanel::JSON::XS::encode_json | str1k           | 4.07e+05    | 0.00246     | 3.3e-09 | 20      |
 | Data::MessagePack::pack       | hash_int_10     | 4.288e+05   | 0.0023321   | 1.1e-11 | 20      |
 | JSON::XS::encode_json         | str1k           | 4.31e+05    | 0.00232     | 3.3e-09 | 20      |
 | JSON::MaybeXS::encode_json    | hash_int_10     | 4.78e+05    | 0.00209     | 8.3e-10 | 20      |
 | Cpanel::JSON::XS::encode_json | hash_int_10     | 4.88e+05    | 0.00205     | 4.2e-09 | 20      |
 | JSON::XS::encode_json         | hash_int_10     | 4.92e+05    | 0.00203     | 2.5e-09 | 20      |
 | JSON::Create::create_json     | hash_int_10     | 5.28e+05    | 0.00189     | 4.2e-09 | 20      |
 | Sereal::encode_sereal         | array_int_10    | 1.17e+06    | 0.000857    | 4.2e-10 | 20      |
 | JSON::XS::encode_json         | array_int_10    | 1.263e+06   | 0.00079176  | 1.2e-11 | 20      |
 | JSON::MaybeXS::encode_json    | array_int_10    | 1.28e+06    | 0.000784    | 1.7e-09 | 20      |
 | Cpanel::JSON::XS::encode_json | array_int_10    | 1.28e+06    | 0.000778    | 1.7e-09 | 20      |
 | Data::MessagePack::pack       | array_int_10    | 1.36e+06    | 0.000737    | 3.9e-10 | 30      |
 | JSON::XS::encode_json         | num             | 1.4e+06     | 0.0007      | 6.7e-09 | 21      |
 | JSON::Create::create_json     | array_int_10    | 1.505e+06   | 0.0006644   | 2.1e-10 | 20      |
 | JSON::MaybeXS::encode_json    | num             | 1.57e+06    | 0.000635    | 8.3e-10 | 20      |
 | Cpanel::JSON::XS::encode_json | num             | 1.6412e+06  | 0.00060931  | 1.2e-11 | 25      |
 | Sereal::encode_sereal         | str1k           | 1.9e+06     | 0.00054     | 2.9e-09 | 27      |
 | Sereal::encode_sereal         | str1k           | 2.13e+06    | 0.00047     | 9.5e-10 | 24      |
 | JSON::Create::create_json     | num             | 2.2201e+06  | 0.00045042  | 1.2e-11 | 20      |
 | Data::MessagePack::pack       | str1k           | 2.31e+06    | 0.000433    | 8.3e-10 | 20      |
 | Data::MessagePack::pack       | str1k           | 2.642e+06   | 0.0003785   | 3.5e-11 | 20      |
 | Sereal::encode_sereal         | num             | 2.73014e+06 | 0.000366282 | 0       | 20      |
 | Sereal::encode_sereal         | undef           | 3.09e+06    | 0.000324    | 1.7e-10 | 32      |
 | JSON::XS::encode_json         | undef           | 4.24e+06    | 0.000236    | 1e-10   | 20      |
 | Data::MessagePack::pack       | num             | 4.26e+06    | 0.000235    | 3.1e-10 | 20      |
 | Data::MessagePack::pack       | undef           | 4.619e+06   | 0.0002165   | 1e-11   | 20      |
 | JSON::MaybeXS::encode_json    | undef           | 4.97e+06    | 0.000201    | 1e-10   | 21      |
 | Cpanel::JSON::XS::encode_json | undef           | 5.16e+06    | 0.000194    | 1e-10   | 20      |
 | JSON::Create::create_json     | undef           | 5.7e+06     | 0.00018     | 7.9e-10 | 22      |
 +-------------------------------+-----------------+-------------+-------------+---------+---------+


Benchmark deserializing (C<< bencher -m Serializers --include-participant-tags-json '["deserialize"]' >>):

 +---------------------------------+---------------------+------------+-----------+---------+---------+
 | participant                     | dataset             | rate (/s)  | time (ms) | errors  | samples |
 +---------------------------------+---------------------+------------+-----------+---------+---------+
 | JSON::Decode::Regexp::from_json | json:hash_int_1000  | 6.5        | 1.5e+02   | 0.00076 | 20      |
 | Pegex::JSON                     | json:hash_int_1000  | 15.2       | 65.8      | 9.9e-05 | 20      |
 | JSON::Decode::Marpa::from_json  | json:hash_int_1000  | 17.7       | 56.5      | 6.5e-05 | 20      |
 | Pegex::JSON                     | json:array_int_1000 | 26.9       | 37.2      | 2.1e-05 | 21      |
 | JSON::Decode::Regexp::from_json | json:array_int_1000 | 37         | 27        | 0.00015 | 20      |
 | JSON::Decode::Marpa::from_json  | json:array_int_1000 | 39.2       | 25.5      | 3.3e-05 | 21      |
 | JSON::PP::decode_json           | json:hash_int_1000  | 88.3       | 11.3      | 6.1e-06 | 20      |
 | JSON::Decode::Marpa::from_json  | json:array_str1k_10 | 93.5       | 10.7      | 8.3e-06 | 21      |
 | JSON::PP::decode_json           | json:array_str1k_10 | 133        | 7.5       | 3.6e-06 | 20      |
 | Pegex::JSON                     | json:hash_int_100   | 143        | 6.99      | 1.5e-05 | 20      |
 | JSON::Decode::Marpa::from_json  | json:hash_int_100   | 159        | 6.31      | 7.6e-06 | 20      |
 | JSON::PP::decode_json           | json:array_int_1000 | 175.9      | 5.685     | 1.3e-06 | 20      |
 | Pegex::JSON                     | json:array_int_100  | 251        | 3.99      | 2.7e-06 | 20      |
 | JSON::Decode::Regexp::from_json | json:hash_int_100   | 313        | 3.2       | 4.7e-06 | 20      |
 | JSON::Decode::Marpa::from_json  | json:array_int_100  | 319        | 3.13      | 1.6e-06 | 20      |
 | Pegex::JSON                     | json:array_str1k_10 | 599        | 1.67      | 3.8e-06 | 20      |
 | JSON::Decode::Marpa::from_json  | json:hash_int_10    | 738        | 1.35      | 1.1e-06 | 21      |
 | JSON::Decode::Regexp::from_json | json:array_int_100  | 881        | 1.14      | 1.3e-06 | 20      |
 | Pegex::JSON                     | json:hash_int_10    | 900        | 1.11      | 5.2e-07 | 21      |
 | JSON::PP::decode_json           | json:hash_int_100   | 954        | 1.05      | 6.4e-07 | 20      |
 | JSON::Decode::Marpa::from_json  | json:array_int_10   | 979        | 1.02      | 4.3e-07 | 20      |
 | Pegex::JSON                     | json:array_int_10   | 1.21e+03   | 0.824     | 9.1e-07 | 20      |
 | JSON::PP::decode_json           | json:str1k          | 1.3e+03    | 0.767     | 9.1e-07 | 20      |
 | JSON::PP::decode_json           | json:array_int_100  | 1.9e+03    | 0.525     | 2.7e-07 | 20      |
 | Pegex::JSON                     | json:str1k          | 1.95e+03   | 0.514     | 4.3e-07 | 20      |
 | Pegex::JSON                     | json:null           | 2.16e+03   | 0.462     | 4.3e-07 | 20      |
 | Pegex::JSON                     | json:num            | 2.27e+03   | 0.44      | 2.7e-07 | 20      |
 | JSON::Decode::Regexp::from_json | json:array_str1k_10 | 3.46e+03   | 0.289     | 4.3e-07 | 20      |
 | JSON::Decode::Regexp::from_json | json:hash_int_10    | 3.53e+03   | 0.284     | 4.3e-07 | 20      |
 | JSON::Decode::Regexp::from_json | json:array_int_10   | 5.76e+03   | 0.173     | 4.3e-07 | 20      |
 | JSON::Parse::parse_json         | json:hash_int_1000  | 6.63e+03   | 0.151     | 2.1e-07 | 20      |
 | Cpanel::JSON::XS::decode_json   | json:hash_int_1000  | 7.03e+03   | 0.142     | 2.1e-07 | 20      |
 | JSON::MaybeXS::decode_json      | json:hash_int_1000  | 7.05e+03   | 0.142     | 1.5e-07 | 24      |
 | JSON::XS::decode_json           | json:hash_int_1000  | 7.1e+03    | 0.141     | 2.1e-07 | 20      |
 | JSON::PP::decode_json           | json:hash_int_10    | 9.15e+03   | 0.109     | 5.3e-08 | 20      |
 | JSON::Decode::Regexp::from_json | json:str1k          | 1.15e+04   | 0.0869    | 1.3e-07 | 21      |
 | JSON::Decode::Regexp::from_json | json:num            | 1.25e+04   | 0.0797    | 1e-07   | 22      |
 | JSON::Decode::Regexp::from_json | json:null           | 1.55e+04   | 0.0646    | 1e-07   | 21      |
 | JSON::PP::decode_json           | json:array_int_10   | 1.74e+04   | 0.0573    | 7.5e-08 | 23      |
 | JSON::Parse::parse_json         | json:array_int_1000 | 2.71e+04   | 0.0369    | 5.3e-08 | 20      |
 | JSON::MaybeXS::decode_json      | json:array_int_1000 | 2.92e+04   | 0.0343    | 5.3e-08 | 20      |
 | Cpanel::JSON::XS::decode_json   | json:array_int_1000 | 2.93e+04   | 0.0341    | 4e-08   | 20      |
 | JSON::XS::decode_json           | json:array_int_1000 | 29602.1    | 0.0337814 | 1.2e-11 | 20      |
 | JSON::Parse::parse_json         | json:array_str1k_10 | 3.62e+04   | 0.0276    | 5.3e-08 | 20      |
 | Cpanel::JSON::XS::decode_json   | json:array_str1k_10 | 5.1e+04    | 0.0196    | 6.7e-09 | 20      |
 | JSON::MaybeXS::decode_json      | json:array_str1k_10 | 51203.7    | 0.0195299 | 1.1e-11 | 20      |
 | JSON::XS::decode_json           | json:array_str1k_10 | 6.61e+04   | 0.0151    | 6.4e-09 | 22      |
 | JSON::PP::decode_json           | json:num            | 7.05e+04   | 0.0142    | 5.8e-09 | 26      |
 | JSON::Parse::parse_json         | json:hash_int_100   | 8.95e+04   | 0.0112    | 2.7e-08 | 25      |
 | JSON::MaybeXS::decode_json      | json:hash_int_100   | 8.95e+04   | 0.0112    | 1.3e-08 | 20      |
 | Cpanel::JSON::XS::decode_json   | json:hash_int_100   | 9.09e+04   | 0.011     | 1e-08   | 20      |
 | JSON::XS::decode_json           | json:hash_int_100   | 9.31e+04   | 0.0107    | 1.3e-08 | 21      |
 | JSON::PP::decode_json           | json:null           | 1.31e+05   | 0.00763   | 3.3e-09 | 20      |
 | JSON::XS::decode_json           | json:array_int_100  | 2.37e+05   | 0.00422   | 6.7e-09 | 20      |
 | Cpanel::JSON::XS::decode_json   | json:array_int_100  | 2.4e+05    | 0.0041    | 2.7e-08 | 20      |
 | JSON::MaybeXS::decode_json      | json:array_int_100  | 2.43e+05   | 0.00412   | 8.3e-09 | 20      |
 | JSON::Parse::parse_json         | json:array_int_100  | 2.44e+05   | 0.0041    | 1.6e-09 | 22      |
 | JSON::Parse::parse_json         | json:str1k          | 3.67e+05   | 0.00273   | 3e-09   | 38      |
 | JSON::MaybeXS::decode_json      | json:str1k          | 5.15e+05   | 0.00194   | 8.3e-10 | 20      |
 | Cpanel::JSON::XS::decode_json   | json:str1k          | 5.2e+05    | 0.0019    | 8.9e-09 | 25      |
 | JSON::XS::decode_json           | json:str1k          | 6.5332e+05 | 0.0015307 | 3.5e-11 | 20      |
 | JSON::Parse::parse_json         | json:hash_int_10    | 8.5e+05    | 0.0012    | 3.9e-09 | 27      |
 | JSON::MaybeXS::decode_json      | json:hash_int_10    | 8.62e+05   | 0.00116   | 3.3e-09 | 20      |
 | Cpanel::JSON::XS::decode_json   | json:hash_int_10    | 8.62e+05   | 0.00116   | 1.7e-09 | 20      |
 | JSON::XS::decode_json           | json:hash_int_10    | 8.81e+05   | 0.00113   | 1.3e-09 | 20      |
 | JSON::MaybeXS::decode_json      | json:num            | 9.9e+05    | 0.00101   | 1.2e-09 | 20      |
 | Cpanel::JSON::XS::decode_json   | json:num            | 1e+06      | 0.000997  | 3.7e-10 | 30      |
 | JSON::XS::decode_json           | json:num            | 1.03e+06   | 0.000973  | 1.7e-09 | 20      |
 | JSON::Parse::parse_json         | json:num            | 1.05e+06   | 0.000952  | 1.7e-09 | 20      |
 | JSON::XS::decode_json           | json:array_int_10   | 1.425e+06  | 0.0007017 | 2.1e-10 | 20      |
 | Cpanel::JSON::XS::decode_json   | json:array_int_10   | 1.52e+06   | 0.000658  | 2.1e-10 | 20      |
 | JSON::MaybeXS::decode_json      | json:array_int_10   | 1.5e+06    | 0.00065   | 4.4e-09 | 20      |
 | JSON::Parse::parse_json         | json:array_int_10   | 1.559e+06  | 0.0006414 | 9.6e-11 | 20      |
 | Cpanel::JSON::XS::decode_json   | json:null           | 6.925e+06  | 0.0001444 | 4.5e-11 | 20      |
 | JSON::MaybeXS::decode_json      | json:null           | 6.974e+06  | 0.0001434 | 1.2e-11 | 20      |
 | JSON::XS::decode_json           | json:null           | 7.1e+06    | 0.00014   | 5e-10   | 22      |
 | JSON::Parse::parse_json         | json:null           | 7.82e+06   | 0.000128  | 1e-10   | 20      |
 +---------------------------------+---------------------+------------+-----------+---------+---------+


Benchmark module startup overhead (C<< bencher -m Serializers --module-startup >>):

 +----------------------+-----------+------------------------+---------+---------+
 | participant          | time (ms) | mod_overhead_time (ms) | errors  | samples |
 +----------------------+-----------+------------------------+---------+---------+
 | JSON::Decode::Marpa  | 1.3e+02   | 121.7                  | 0.00072 | 20      |
 | YAML::XS             | 55        | 46.7                   | 0.00036 | 20      |
 | JSON::PP             | 27        | 18.7                   | 0.00021 | 20      |
 | Pegex::JSON          | 25        | 16.7                   | 0.00014 | 20      |
 | JSON::MaybeXS        | 19        | 10.7                   | 4.5e-05 | 20      |
 | Sereal               | 18        | 9.7                    | 0.00021 | 20      |
 | Storable             | 17        | 8.7                    | 8.6e-05 | 21      |
 | YAML::Old            | 15.8      | 7.5                    | 2.9e-05 | 21      |
 | JSON::XS             | 14.1      | 5.8                    | 2.8e-05 | 20      |
 | JSON::Parse          | 14        | 5.7                    | 6.3e-05 | 20      |
 | Cpanel::JSON::XS     | 14        | 5.7                    | 5.4e-05 | 20      |
 | YAML::Syck           | 13.2      | 4.9                    | 3.9e-05 | 20      |
 | JSON::Create         | 11        | 2.7                    | 4.6e-05 | 20      |
 | JSON::Decode::Regexp | 10        | 1.7                    | 4.7e-05 | 20      |
 | Data::MessagePack    | 10.4      | 2.1                    | 2.9e-05 | 20      |
 | perl -e1 (baseline)  | 8.3       | 0                      | 0.00014 | 20      |
 +----------------------+-----------+------------------------+---------+---------+

=head1 DESCRIPTION

Packaging a benchmark script as a Bencher scenario makes it convenient to include/exclude/add participants/datasets (either via CLI or Perl code), send the result to a central repository, among others . See L<Bencher> and L<bencher> (CLI) for more details.

=head1 HOMEPAGE

Please visit the project's homepage at L<https://metacpan.org/release/Bencher-Scenario-Serializers>.

=head1 SOURCE

Source repository is at L<https://github.com/perlancar/perl-Bencher-Scenario-Serializers>.

=head1 BUGS

Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Bencher-Scenario-Serializers>

When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.

=head1 AUTHOR

perlancar <perlancar@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2016 by perlancar@cpan.org.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
