package Bencher::Scenario::Serializers;

our $DATE = '2016-02-18'; # DATE
our $VERSION = '0.11'; # 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'],
            fcall_template => 'PERLANCAR::JSON::Match::match_json(<data>)',
            include_by_default => 0,
        },
        {
            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.11 of Bencher::Scenario::Serializers (from Perl distribution Bencher-Scenario-Serializers), released on 2016-02-18.

=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

Version numbers shown below are the versions used when running the sample benchmark.

L<JSON::PP> 2.27300

L<JSON::XS> 3.01

L<Cpanel::JSON::XS> 3.0211

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.19

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) [json, serialize]

Code template:

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



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

Code template:

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



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

Code template:

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



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

Code template:

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



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

Code template:

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



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

Code template:

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



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

Code template:

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



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

Code template:

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



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

Function call template:

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



=item * PERLANCAR::JSON::Match::match_json (perl_code) (not included by default) [json, deserialize, cant_handle_scalar]

Function call template:

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



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

Code template:

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



=item * Pegex::JSON (perl_code) [json, serialize]

Function call template:

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



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

Function call template:

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



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

Function call template:

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



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

Function call template:

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



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

Function call template:

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



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

Function call template:

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



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

Function call template:

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



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

Function call template:

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



=item * YAML::XS::Load (perl_code) [binary, serialize, cant_handle_scalar]

Function call template:

 Storable::freeze(<data>)



=item * Storable::freeze (perl_code) [binary, deserialize, cant_handle_scalar]

Function call template:

 Storable::thaw(<data>)



=item * Storable::thaw (perl_code) [binary, serialize]

Function call template:

 Sereal::encode_sereal(<data>)



=item * Sereal::encode_sereal (perl_code) [binary, deserialize]

Function call template:

 Sereal::decode_sereal(<data>)



=item * Sereal::decode_sereal (perl_code) [binary, serialize]

Code template:

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



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

Code template:

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



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

L<Data::MessagePack>::unpack



=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.2      | 41.4      | 3.7e-05 | 20      |
 | YAML::Old::Dump               | array_int_1000  | 31        | 32        | 8.9e-05 | 20      |
 | JSON::PP::encode_json         | hash_int_1000   | 228       | 4.39      | 2.7e-06 | 20      |
 | YAML::Old::Dump               | hash_int_100    | 2.3e+02   | 4.3       | 1.2e-05 | 20      |
 | YAML::Old::Dump               | array_int_100   | 307       | 3.26      | 2.5e-06 | 20      |
 | JSON::PP::encode_json         | array_int_1000  | 5.8e+02   | 1.7       | 2.2e-06 | 20      |
 | YAML::Syck::Dump              | hash_int_1000   | 6.9e+02   | 1.5       | 3.1e-06 | 20      |
 | YAML::XS::Dump                | hash_int_1000   | 7e+02     | 1.4       | 3.1e-06 | 24      |
 | YAML::Old::Dump               | array_ustr1k_10 | 868       | 1.15      | 4.3e-07 | 20      |
 | YAML::Syck::Dump              | array_int_1000  | 1.6e+03   | 0.61      | 1.8e-06 | 20      |
 | YAML::XS::Dump                | array_int_1000  | 1.7e+03   | 0.57      | 1.1e-06 | 20      |
 | JSON::PP::encode_json         | array_ustr1k_10 | 1.9e+03   | 0.54      | 6.4e-07 | 20      |
 | YAML::Old::Dump               | array_str1k_10  | 1.99e+03  | 0.503     | 3.7e-07 | 20      |
 | YAML::Old::Dump               | hash_int_10     | 1.99e+03  | 0.502     | 2.7e-07 | 20      |
 | JSON::PP::encode_json         | hash_int_100    | 2.2e+03   | 0.45      | 1.1e-06 | 21      |
 | YAML::Old::Dump               | array_int_10    | 2.5e+03   | 0.4       | 2.5e-06 | 20      |
 | YAML::XS::Dump                | array_ustr1k_10 | 3.05e+03  | 0.328     | 5.3e-08 | 20      |
 | Cpanel::JSON::XS::encode_json | array_ustr1k_10 | 3.38e+03  | 0.296     | 5.3e-08 | 20      |
 | JSON::MaybeXS::encode_json    | array_ustr1k_10 | 3.39e+03  | 0.295     | 1.6e-07 | 21      |
 | JSON::XS::encode_json         | array_ustr1k_10 | 3.5e+03   | 0.28      | 6.9e-07 | 20      |
 | Sereal::encode_sereal         | hash_int_1000   | 3.71e+03  | 0.269     | 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.37e+03  | 0.229     | 1.6e-07 | 20      |
 | JSON::MaybeXS::encode_json    | hash_int_1000   | 4.9e+03   | 0.2       | 2.1e-07 | 20      |
 | JSON::XS::encode_json         | hash_int_1000   | 4.9e+03   | 0.2       | 6.4e-07 | 20      |
 | Cpanel::JSON::XS::encode_json | hash_int_1000   | 4.9e+03   | 0.2       | 2.3e-07 | 26      |
 | JSON::Create::create_json     | hash_int_1000   | 5.1e+03   | 0.2       | 2.4e-07 | 25      |
 | JSON::PP::encode_json         | array_int_100   | 5.5e+03   | 0.18      | 2.7e-07 | 20      |
 | YAML::Old::Dump               | str1k           | 6.7e+03   | 0.15      | 2.6e-07 | 21      |
 | YAML::Syck::Dump              | array_ustr1k_10 | 6.76e+03  | 0.148     | 5.3e-08 | 20      |
 | YAML::Syck::Dump              | hash_int_100    | 6.9e+03   | 0.14      | 9.1e-07 | 20      |
 | YAML::XS::Dump                | array_str1k_10  | 7237.9    | 0.13816   | 1.8e-10 | 22      |
 | YAML::XS::Dump                | hash_int_100    | 7.3e+03   | 0.14      | 2.5e-07 | 22      |
 | JSON::PP::encode_json         | array_str1k_10  | 1.03e+04  | 0.0967    | 8e-08   | 20      |
 | YAML::Old::Dump               | str1k           | 1.2e+04   | 0.08      | 1e-07   | 21      |
 | YAML::Old::Dump               | num             | 1.3e+04   | 0.076     | 3.5e-07 | 20      |
 | Storable::freeze              | array_int_1000  | 1.4e+04   | 0.071     | 1.2e-07 | 24      |
 | JSON::Create::create_json     | array_ustr1k_10 | 14352     | 0.069675  | 9.1e-11 | 20      |
 | YAML::Old::Dump               | undef           | 1.5e+04   | 0.066     | 1.1e-07 | 20      |
 | YAML::XS::Dump                | array_int_100   | 1.6e+04   | 0.062     | 1.7e-07 | 23      |
 | YAML::Syck::Dump              | array_int_100   | 1.6e+04   | 0.062     | 1.1e-07 | 20      |
 | JSON::PP::encode_json         | str1k           | 1.8e+04   | 0.055     | 1.1e-07 | 20      |
 | JSON::PP::encode_json         | hash_int_10     | 1.86e+04  | 0.0537    | 2.5e-08 | 22      |
 | YAML::Syck::Dump              | array_str1k_10  | 2e+04     | 0.051     | 1.1e-07 | 20      |
 | JSON::MaybeXS::encode_json    | array_int_1000  | 2.1e+04   | 0.048     | 2.7e-07 | 20      |
 | Cpanel::JSON::XS::encode_json | array_int_1000  | 2.1e+04   | 0.048     | 5.3e-08 | 20      |
 | JSON::XS::encode_json         | array_int_1000  | 2.1e+04   | 0.048     | 5.5e-08 | 29      |
 | Cpanel::JSON::XS::encode_json | str1k           | 2.2e+04   | 0.045     | 5.4e-08 | 31      |
 | JSON::XS::encode_json         | str1k           | 2.26e+04  | 0.0443    | 4e-08   | 20      |
 | JSON::MaybeXS::encode_json    | str1k           | 2.3e+04   | 0.044     | 1.7e-07 | 20      |
 | JSON::Create::create_json     | array_int_1000  | 2.3e+04   | 0.044     | 6.4e-08 | 22      |
 | Data::MessagePack::pack       | array_int_1000  | 2.7e+04   | 0.037     | 4.6e-08 | 27      |
 | Sereal::encode_sereal         | array_int_1000  | 2.82e+04  | 0.0355    | 1.1e-08 | 30      |
 | YAML::XS::Dump                | str1k           | 2.83e+04  | 0.0353    | 1.3e-08 | 21      |
 | JSON::Create::create_json     | array_str1k_10  | 38843     | 0.025745  | 1.8e-10 | 20      |
 | Storable::freeze              | hash_int_100    | 4.2e+04   | 0.024     | 2.7e-08 | 20      |
 | JSON::PP::encode_json         | array_int_10    | 4.26e+04  | 0.0235    | 6.7e-09 | 20      |
 | Sereal::encode_sereal         | hash_int_100    | 4.4e+04   | 0.023     | 5.6e-08 | 23      |
 | JSON::MaybeXS::encode_json    | array_str1k_10  | 4.5e+04   | 0.022     | 2.7e-08 | 20      |
 | Cpanel::JSON::XS::encode_json | array_str1k_10  | 4.5e+04   | 0.022     | 2.7e-08 | 20      |
 | JSON::XS::encode_json         | array_str1k_10  | 4.57e+04  | 0.0219    | 6.7e-09 | 20      |
 | Data::MessagePack::pack       | hash_int_100    | 4.7e+04   | 0.021     | 1.1e-07 | 21      |
 | YAML::Syck::Dump              | hash_int_10     | 4.9e+04   | 0.02      | 2.4e-08 | 24      |
 | YAML::Syck::Dump              | str1k           | 5.42e+04  | 0.0185    | 6.7e-09 | 20      |
 | JSON::MaybeXS::encode_json    | hash_int_100    | 5.6e+04   | 0.018     | 2.7e-08 | 20      |
 | JSON::XS::encode_json         | hash_int_100    | 5.6e+04   | 0.018     | 2.7e-08 | 20      |
 | Cpanel::JSON::XS::encode_json | hash_int_100    | 5.6e+04   | 0.018     | 3.3e-08 | 20      |
 | YAML::XS::Dump                | hash_int_10     | 5.7e+04   | 0.018     | 4.9e-08 | 24      |
 | JSON::Create::create_json     | hash_int_100    | 6.1e+04   | 0.016     | 2.7e-08 | 20      |
 | YAML::XS::Dump                | str1k           | 6.21e+04  | 0.0161    | 6.7e-09 | 20      |
 | YAML::Syck::Dump              | array_int_10    | 84947     | 0.011772  | 9.1e-11 | 20      |
 | JSON::PP::encode_json         | str1k           | 9.1e+04   | 0.011     | 3e-08   | 20      |
 | YAML::XS::Dump                | array_int_10    | 9.8e+04   | 0.01      | 4e-08   | 20      |
 | YAML::Syck::Dump              | str1k           | 1e+05     | 0.0098    | 1e-08   | 20      |
 | Storable::freeze              | array_int_100   | 1.1e+05   | 0.0095    | 1e-08   | 20      |
 | Storable::freeze              | array_ustr1k_10 | 1.3e+05   | 0.0078    | 3.9e-08 | 21      |
 | YAML::Syck::Dump              | num             | 1.3e+05   | 0.0078    | 1.6e-08 | 22      |
 | JSON::Create::create_json     | str1k           | 1.377e+05 | 0.007265  | 9.2e-11 | 21      |
 | Storable::freeze              | hash_int_10     | 1.4e+05   | 0.0072    | 1.4e-08 | 28      |
 | YAML::Syck::Dump              | undef           | 1.7e+05   | 0.0057    | 1.4e-08 | 22      |
 | Storable::freeze              | array_str1k_10  | 1.8e+05   | 0.0057    | 6.5e-09 | 21      |
 | Cpanel::JSON::XS::encode_json | array_int_100   | 1.8e+05   | 0.0054    | 6.7e-09 | 20      |
 | JSON::MaybeXS::encode_json    | array_int_100   | 1.9e+05   | 0.0053    | 1.3e-08 | 20      |
 | JSON::XS::encode_json         | array_int_100   | 1.9e+05   | 0.0053    | 1.3e-08 | 20      |
 | JSON::PP::encode_json         | num             | 1.9e+05   | 0.0052    | 1.5e-08 | 20      |
 | YAML::XS::Dump                | num             | 2.1e+05   | 0.0049    | 8.3e-09 | 20      |
 | Storable::freeze              | array_int_10    | 2.2e+05   | 0.0045    | 6.7e-09 | 20      |
 | Data::MessagePack::pack       | array_ustr1k_10 | 2.4e+05   | 0.0042    | 6.5e-09 | 21      |
 | JSON::Create::create_json     | array_int_100   | 2.359e+05 | 0.004238  | 1.9e-10 | 20      |
 | Data::MessagePack::pack       | array_int_100   | 2.37e+05  | 0.00421   | 1.6e-09 | 21      |
 | Sereal::encode_sereal         | array_ustr1k_10 | 2.428e+05 | 0.004118  | 9.3e-11 | 20      |
 | Sereal::encode_sereal         | array_int_100   | 2.508e+05 | 0.003987  | 3e-10   | 20      |
 | JSON::PP::encode_json         | undef           | 3.059e+05 | 0.003269  | 1.8e-10 | 20      |
 | Data::MessagePack::pack       | array_str1k_10  | 3.4e+05   | 0.003     | 8.3e-09 | 29      |
 | JSON::Create::create_json     | str1k           | 3.7e+05   | 0.0027    | 3.4e-09 | 30      |
 | Sereal::encode_sereal         | array_str1k_10  | 3.7e+05   | 0.0027    | 3e-09   | 24      |
 | JSON::MaybeXS::encode_json    | str1k           | 3.9e+05   | 0.0026    | 6.7e-09 | 20      |
 | YAML::XS::Dump                | undef           | 4e+05     | 0.0025    | 3.3e-09 | 20      |
 | Cpanel::JSON::XS::encode_json | str1k           | 4e+05     | 0.0025    | 3.3e-09 | 20      |
 | Data::MessagePack::pack       | hash_int_10     | 4.1e+05   | 0.0024    | 3.1e-09 | 23      |
 | Sereal::encode_sereal         | hash_int_10     | 4.2e+05   | 0.0024    | 1.3e-08 | 20      |
 | JSON::XS::encode_json         | str1k           | 4.2e+05   | 0.0024    | 3.3e-09 | 20      |
 | Cpanel::JSON::XS::encode_json | hash_int_10     | 4.6e+05   | 0.0022    | 9.8e-09 | 21      |
 | JSON::MaybeXS::encode_json    | hash_int_10     | 4.6e+05   | 0.0022    | 3.3e-09 | 20      |
 | JSON::XS::encode_json         | hash_int_10     | 4.7e+05   | 0.0021    | 4.2e-09 | 20      |
 | JSON::Create::create_json     | hash_int_10     | 5.3e+05   | 0.0019    | 3e-09   | 24      |
 | Sereal::encode_sereal         | array_int_10    | 1.2e+06   | 0.00087   | 1.7e-09 | 20      |
 | JSON::MaybeXS::encode_json    | array_int_10    | 1.2e+06   | 0.00084   | 6.7e-09 | 25      |
 | Cpanel::JSON::XS::encode_json | array_int_10    | 1.2e+06   | 0.000836  | 4e-10   | 23      |
 | JSON::XS::encode_json         | array_int_10    | 1.27e+06  | 0.000788  | 8.8e-11 | 20      |
 | Data::MessagePack::pack       | array_int_10    | 1.34e+06  | 0.000749  | 9.1e-11 | 20      |
 | JSON::MaybeXS::encode_json    | num             | 1.39e+06  | 0.00072   | 4.2e-10 | 25      |
 | Cpanel::JSON::XS::encode_json | num             | 1.41e+06  | 0.000709  | 3.5e-10 | 32      |
 | JSON::Create::create_json     | array_int_10    | 1.5e+06   | 0.00068   | 8.5e-10 | 20      |
 | JSON::XS::encode_json         | num             | 1.5e+06   | 0.00067   | 1e-09   | 20      |
 | Sereal::encode_sereal         | str1k           | 1.8e+06   | 0.00056   | 1e-09   | 22      |
 | Sereal::encode_sereal         | str1k           | 2.06e+06  | 0.000485  | 1.8e-10 | 20      |
 | JSON::Create::create_json     | num             | 2.21e+06  | 0.000453  | 9.2e-11 | 23      |
 | Data::MessagePack::pack       | str1k           | 2.31e+06  | 0.000434  | 1.6e-10 | 20      |
 | Sereal::encode_sereal         | num             | 2.4e+06   | 0.00041   | 6.6e-10 | 20      |
 | Data::MessagePack::pack       | str1k           | 2.68e+06  | 0.000373  | 9.1e-11 | 20      |
 | Sereal::encode_sereal         | undef           | 2.89e+06  | 0.000346  | 2.3e-10 | 20      |
 | JSON::MaybeXS::encode_json    | undef           | 4.1e+06   | 0.00024   | 9.5e-10 | 20      |
 | Cpanel::JSON::XS::encode_json | undef           | 4.1e+06   | 0.00024   | 9.4e-10 | 20      |
 | Data::MessagePack::pack       | num             | 4.34e+06  | 0.000231  | 1.8e-10 | 20      |
 | JSON::XS::encode_json         | undef           | 5e+06     | 0.0002    | 1.4e-09 | 20      |
 | Data::MessagePack::pack       | undef           | 5.03e+06  | 0.000199  | 1.1e-10 | 20      |
 | JSON::Create::create_json     | undef           | 5.32e+06  | 0.000188  | 1.8e-10 | 20      |
 +-------------------------------+-----------------+-----------+-----------+---------+---------+


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.6       | 1.5e+02   | 0.0012  | 20      |
 | Pegex::JSON                        | json:hash_int_1000  | 15.1      | 66.1      | 9.6e-06 | 20      |
 | JSON::Decode::Marpa::from_json     | json:hash_int_1000  | 17        | 58        | 9.7e-05 | 20      |
 | Pegex::JSON                        | json:array_int_1000 | 26.6      | 37.6      | 2.8e-05 | 20      |
 | JSON::Decode::Regexp::from_json    | json:array_int_1000 | 35        | 28        | 0.00012 | 22      |
 | JSON::Decode::Marpa::from_json     | json:array_int_1000 | 38        | 26        | 4.8e-05 | 20      |
 | JSON::PP::decode_json              | json:hash_int_1000  | 84.3      | 11.9      | 4.6e-06 | 20      |
 | JSON::Decode::Marpa::from_json     | json:array_str1k_10 | 93        | 11        | 1.2e-05 | 20      |
 | JSON::PP::decode_json              | json:array_str1k_10 | 129       | 7.72      | 5.3e-06 | 20      |
 | Pegex::JSON                        | json:hash_int_100   | 143       | 6.98      | 3.1e-06 | 20      |
 | JSON::Decode::Marpa::from_json     | json:hash_int_100   | 158       | 6.32      | 5.8e-06 | 20      |
 | JSON::PP::decode_json              | json:array_int_1000 | 168       | 5.95      | 2.7e-06 | 20      |
 | Pegex::JSON                        | json:array_int_100  | 248       | 4.04      | 2.7e-06 | 20      |
 | JSON::Decode::Regexp::from_json    | json:hash_int_100   | 2.9e+02   | 3.4       | 1e-05   | 20      |
 | JSON::Decode::Marpa::from_json     | json:array_int_100  | 3.2e+02   | 3.2       | 6.7e-06 | 20      |
 | PERLANCAR::JSON::Match::match_json | json:hash_int_1000  | 4.2e+02   | 2.4       | 4.5e-06 | 20      |
 | PERLANCAR::JSON::Match::match_json | json:array_int_1000 | 6e+02     | 2         | 7.4e-05 | 21      |
 | Pegex::JSON                        | json:array_str1k_10 | 603       | 1.66      | 4.8e-07 | 20      |
 | JSON::Decode::Marpa::from_json     | json:hash_int_10    | 732       | 1.37      | 9.1e-07 | 22      |
 | JSON::Decode::Regexp::from_json    | json:array_int_100  | 8.2e+02   | 1.2       | 5.3e-06 | 21      |
 | Pegex::JSON                        | json:hash_int_10    | 893       | 1.12      | 6.4e-07 | 20      |
 | JSON::Decode::Marpa::from_json     | json:array_int_10   | 9e+02     | 1.1       | 8.5e-06 | 20      |
 | JSON::PP::decode_json              | json:hash_int_100   | 9.1e+02   | 1.1       | 1.1e-06 | 20      |
 | Pegex::JSON                        | json:array_int_10   | 1.2e+03   | 0.832     | 6.9e-07 | 20      |
 | JSON::PP::decode_json              | json:str1k          | 1.3e+03   | 0.78      | 1.1e-06 | 20      |
 | JSON::PP::decode_json              | json:array_int_100  | 1.8e+03   | 0.56      | 1.1e-06 | 20      |
 | Pegex::JSON                        | json:str1k          | 1.92e+03  | 0.52      | 4.3e-07 | 20      |
 | Pegex::JSON                        | json:null           | 2.1e+03   | 0.47      | 6.9e-07 | 20      |
 | Pegex::JSON                        | json:num            | 2.23e+03  | 0.448     | 4.3e-07 | 20      |
 | JSON::Decode::Regexp::from_json    | json:array_str1k_10 | 3.4e+03   | 0.3       | 6.9e-07 | 20      |
 | JSON::Decode::Regexp::from_json    | json:hash_int_10    | 3.4e+03   | 0.29      | 4.3e-07 | 20      |
 | PERLANCAR::JSON::Match::match_json | json:hash_int_100   | 4.44e+03  | 0.225     | 2.1e-07 | 20      |
 | JSON::Decode::Regexp::from_json    | json:array_int_10   | 5.6e+03   | 0.18      | 4.3e-07 | 20      |
 | JSON::Parse::parse_json            | json:hash_int_1000  | 6.6e+03   | 0.15      | 2.1e-07 | 20      |
 | JSON::MaybeXS::decode_json         | json:hash_int_1000  | 6.9e+03   | 0.15      | 2.5e-07 | 22      |
 | Cpanel::JSON::XS::decode_json      | json:hash_int_1000  | 7.1e+03   | 0.14      | 1.6e-07 | 20      |
 | JSON::XS::decode_json              | json:hash_int_1000  | 7.1e+03   | 0.14      | 2.1e-07 | 20      |
 | PERLANCAR::JSON::Match::match_json | json:array_int_100  | 7.4e+03   | 0.13      | 4.8e-07 | 20      |
 | JSON::PP::decode_json              | json:hash_int_10    | 8779.59   | 0.113901  | 9.1e-11 | 20      |
 | JSON::Decode::Regexp::from_json    | json:str1k          | 1.1e+04   | 0.088     | 2.1e-07 | 20      |
 | JSON::Decode::Regexp::from_json    | json:num            | 1.2e+04   | 0.081     | 2.1e-07 | 20      |
 | PERLANCAR::JSON::Match::match_json | json:array_str1k_10 | 14337     | 0.069752  | 9.1e-11 | 20      |
 | JSON::Decode::Regexp::from_json    | json:null           | 14986     | 0.06673   | 9.2e-11 | 20      |
 | JSON::PP::decode_json              | json:array_int_10   | 1.7e+04   | 0.06      | 1.1e-07 | 20      |
 | JSON::Parse::parse_json            | json:array_int_1000 | 2.65e+04  | 0.0377    | 1.3e-08 | 22      |
 | JSON::MaybeXS::decode_json         | json:array_int_1000 | 2.88e+04  | 0.0347    | 1.1e-08 | 30      |
 | JSON::XS::decode_json              | json:array_int_1000 | 2.9e+04   | 0.035     | 5.3e-08 | 20      |
 | Cpanel::JSON::XS::decode_json      | json:array_int_1000 | 2.9e+04   | 0.035     | 5.3e-08 | 20      |
 | JSON::Parse::parse_json            | json:array_str1k_10 | 3.6e+04   | 0.027     | 5.1e-08 | 22      |
 | PERLANCAR::JSON::Match::match_json | json:hash_int_10    | 4e+04     | 0.025     | 2.5e-08 | 22      |
 | Cpanel::JSON::XS::decode_json      | json:array_str1k_10 | 4.93e+04  | 0.0203    | 2e-08   | 20      |
 | JSON::MaybeXS::decode_json         | json:array_str1k_10 | 5.09e+04  | 0.0196    | 6.7e-09 | 20      |
 | PERLANCAR::JSON::Match::match_json | json:array_int_10   | 6.2e+04   | 0.016     | 2.8e-08 | 28      |
 | JSON::XS::decode_json              | json:array_str1k_10 | 6.4e+04   | 0.016     | 6.6e-08 | 29      |
 | JSON::PP::decode_json              | json:num            | 6.74e+04  | 0.0148    | 6e-09   | 25      |
 | JSON::Parse::parse_json            | json:hash_int_100   | 8.97e+04  | 0.0111    | 3.3e-09 | 20      |
 | JSON::MaybeXS::decode_json         | json:hash_int_100   | 9e+04     | 0.011     | 2.7e-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.5e+04   | 0.011     | 1.3e-08 | 20      |
 | PERLANCAR::JSON::Match::match_json | json:str1k          | 1.3e+05   | 0.0079    | 1.2e-08 | 25      |
 | JSON::PP::decode_json              | json:null           | 1.3e+05   | 0.0077    | 1.3e-08 | 20      |
 | Cpanel::JSON::XS::decode_json      | json:array_int_100  | 2.3e+05   | 0.0043    | 6.4e-09 | 34      |
 | JSON::MaybeXS::decode_json         | json:array_int_100  | 2.35e+05  | 0.004255  | 9.2e-11 | 20      |
 | JSON::XS::decode_json              | json:array_int_100  | 2.4e+05   | 0.0043    | 6.7e-09 | 20      |
 | JSON::Parse::parse_json            | json:array_int_100  | 2.43e+05  | 0.00411   | 1.6e-09 | 23      |
 | PERLANCAR::JSON::Match::match_json | json:num            | 2.5e+05   | 0.004     | 6.7e-09 | 20      |
 | JSON::Parse::parse_json            | json:str1k          | 3.554e+05 | 0.002814  | 9.1e-11 | 20      |
 | PERLANCAR::JSON::Match::match_json | json:null           | 4.163e+05 | 0.002402  | 9.1e-11 | 20      |
 | Cpanel::JSON::XS::decode_json      | json:str1k          | 4.821e+05 | 0.002074  | 1.8e-10 | 20      |
 | JSON::MaybeXS::decode_json         | json:str1k          | 4.986e+05 | 0.002006  | 9.2e-11 | 20      |
 | JSON::XS::decode_json              | json:str1k          | 6.6e+05   | 0.00151   | 7.4e-10 | 26      |
 | Cpanel::JSON::XS::decode_json      | json:hash_int_10    | 7.7e+05   | 0.0013    | 1.6e-09 | 22      |
 | JSON::MaybeXS::decode_json         | json:hash_int_10    | 7.8e+05   | 0.0013    | 3.7e-09 | 21      |
 | JSON::Parse::parse_json            | json:hash_int_10    | 8.201e+05 | 0.001219  | 9.2e-11 | 20      |
 | JSON::MaybeXS::decode_json         | json:num            | 8.4e+05   | 0.0012    | 6.7e-09 | 20      |
 | JSON::XS::decode_json              | json:hash_int_10    | 8.5e+05   | 0.0012    | 1.5e-09 | 24      |
 | Cpanel::JSON::XS::decode_json      | json:num            | 8.5e+05   | 0.0012    | 3.3e-09 | 20      |
 | JSON::XS::decode_json              | json:num            | 8.6e+05   | 0.0012    | 8.3e-09 | 20      |
 | JSON::Parse::parse_json            | json:num            | 1.1e+06   | 0.00095   | 6.5e-09 | 21      |
 | Cpanel::JSON::XS::decode_json      | json:array_int_10   | 1.28e+06  | 0.000779  | 9.3e-11 | 27      |
 | JSON::MaybeXS::decode_json         | json:array_int_10   | 1.3e+06   | 0.00077   | 2.1e-09 | 20      |
 | JSON::Parse::parse_json            | json:array_int_10   | 1.47e+06  | 0.00068   | 9.3e-11 | 20      |
 | JSON::XS::decode_json              | json:array_int_10   | 1.52e+06  | 0.000656  | 1.9e-10 | 20      |
 | JSON::MaybeXS::decode_json         | json:null           | 6.3e+06   | 0.00016   | 8.4e-10 | 20      |
 | Cpanel::JSON::XS::decode_json      | json:null           | 6.67e+06  | 0.00015   | 1.3e-10 | 26      |
 | JSON::XS::decode_json              | json:null           | 6.98e+06  | 0.000143  | 1.4e-10 | 20      |
 | JSON::Parse::parse_json            | json:null           | 7.7e+06   | 0.00013   | 1.8e-10 | 31      |
 +------------------------------------+---------------------+-----------+-----------+---------+---------+


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   | 122.2                  | 0.00082 | 20      |
 | YAML::XS             | 6e+01     | 52.2                   | 0.0016  | 20      |
 | JSON::PP             | 27        | 19.2                   | 0.00012 | 20      |
 | Pegex::JSON          | 24        | 16.2                   | 0.00017 | 20      |
 | Storable             | 2e+01     | 12.2                   | 0.0003  | 20      |
 | JSON::MaybeXS        | 19        | 11.2                   | 8.6e-05 | 22      |
 | Sereal               | 17        | 9.2                    | 0.00014 | 20      |
 | YAML::Old            | 16        | 8.2                    | 7.9e-05 | 20      |
 | JSON::Parse          | 14        | 6.2                    | 8.7e-05 | 20      |
 | JSON::XS             | 14        | 6.2                    | 3.6e-05 | 21      |
 | YAML::Syck           | 13        | 5.2                    | 6.4e-05 | 20      |
 | Cpanel::JSON::XS     | 13        | 5.2                    | 3.8e-05 | 20      |
 | JSON::Create         | 12        | 4.2                    | 7.9e-05 | 20      |
 | Data::MessagePack    | 10        | 2.2                    | 6.3e-05 | 20      |
 | JSON::Decode::Regexp | 9.8       | 2                      | 2.2e-05 | 20      |
 | perl -e1 (baseline)  | 7.8       | 0                      | 4.3e-05 | 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
