package Bencher::Scenario::TextTableModules;

our $DATE = '2016-01-05'; # DATE
our $VERSION = '0.04'; # VERSION

use 5.010001;
use strict;
use warnings;

sub _make_table {
    my ($cols, $rows) = @_;
    my $res = [];
    push @$res, [];
    for (0..$cols-1) { $res->[0][$_] = "col" . ($_+1) }
    for my $row (1..$rows) {
        push @$res, [ map { "row$row.$_" } 1..$cols ];
    }
    $res;
}

our $scenario = {
    summary => 'Benchmark modules that generate text table',
    participants => [
        {
            module => 'Text::ANSITable',
            code => sub {
                my ($table) = @_;
                my $t = Text::ANSITable->new(
                    use_utf8 => 0,
                    use_box_chars => 0,
                    use_color => 0,
                    columns => $table->[0],
                    border_style => 'Default::single_ascii',
                );
                $t->add_row($table->[$_]) for 1..@$table-1;
                $t->draw;
            },
        },
        {
            module => 'Text::ASCIITable',
            code => sub {
                my ($table) = @_;
                my $t = Text::ASCIITable->new();
                $t->setCols(@{ $table->[0] });
                $t->addRow(@{ $table->[$_] }) for 1..@$table-1;
                "$t";
            },
        },
        {
            module => 'Text::FormatTable',
            code => sub {
                my ($table) = @_;
                my $t = Text::FormatTable->new(join('|', ('l') x @{ $table->[0] }));
                $t->head(@{ $table->[0] });
                $t->row(@{ $table->[$_] }) for 1..@$table-1;
                $t->render;
            },
        },
        {
            module => 'Text::MarkdownTable',
            code => sub {
                my ($table) = @_;
                my $out = "";
                my $t = Text::MarkdownTable->new(file => \$out);
                my $fields = $table->[0];
                foreach (1..@$table-1) {
                    my $row = $table->[$_];
                    $t->add( {
                        map { $fields->[$_] => $row->[$_] } 0..@$fields-1
                    });
                }
                $t->done;
                $out;
            },
        },
        {
            module => 'Text::Table',
            code => sub {
                my ($table) = @_;
                my $t = Text::Table->new(@{ $table->[0] });
                $t->load(@{ $table }[1..@$table-1]);
                $t;
            },
        },
        {
            module => 'Text::Table::Tiny',
            code => sub {
                my ($table) = @_;
                Text::Table::Tiny::table(rows=>$table, header_row=>1);
            },
        },
        {
            module => 'Text::Table::Org',
            code => sub {
                my ($table) = @_;
                Text::Table::Org::table(rows=>$table, header_row=>1);
            },
        },
        {
            module => 'Text::Table::CSV',
            code => sub {
                my ($table) = @_;
                Text::Table::CSV::table(rows=>$table, header_row=>1);
            },
        },
        {
            module => 'Text::TabularDisplay',
            code => sub {
                my ($table) = @_;
                my $t = Text::TabularDisplay->new(@{ $table->[0] });
                $t->add(@{ $table->[$_] }) for 1..@$table-1;
                $t->render; # doesn't add newline
            },
        },
    ],

    datasets => [
        {name=>'tiny (1x1)'    , argv => [_make_table( 1, 1)],},
        {name=>'small (3x5)'   , argv => [_make_table( 3, 5)],},
        {name=>'wide (30x5)'   , argv => [_make_table(30, 5)],},
        {name=>'long (3x300)'  , argv => [_make_table( 3, 300)],},
        {name=>'large (30x300)', argv => [_make_table(30, 300)],},
    ],

};

1;
# ABSTRACT: Benchmark modules that generate text table

__END__

=pod

=encoding UTF-8

=head1 NAME

Bencher::Scenario::TextTableModules

=head1 VERSION

This document describes version 0.04 of Bencher::Scenario::TextTableModules (from Perl distribution Bencher-Scenario-TextTableModules), released on 2016-01-05.

=head1 SYNOPSIS

To run benchmark with default option:

 % bencher -m TextTableModules

To run module startup overhead benchmark:

 % bencher --module-startup -m TextTableModules

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<Text::ANSITable> 0.46

L<Text::ASCIITable> 0.20

L<Text::FormatTable> 1.03

L<Text::MarkdownTable> 0.3.1

L<Text::Table> 1.130

L<Text::Table::Tiny> 0.04

L<Text::Table::Org> 0.02

L<Text::Table::CSV> 0.01

L<Text::TabularDisplay> 1.38

=head1 BENCHMARK PARTICIPANTS

=over

=item * Text::ANSITable (perl_code)

L<Text::ANSITable>



=item * Text::ASCIITable (perl_code)

L<Text::ASCIITable>



=item * Text::FormatTable (perl_code)

L<Text::FormatTable>



=item * Text::MarkdownTable (perl_code)

L<Text::MarkdownTable>



=item * Text::Table (perl_code)

L<Text::Table>



=item * Text::Table::Tiny (perl_code)

L<Text::Table::Tiny>



=item * Text::Table::Org (perl_code)

L<Text::Table::Org>



=item * Text::Table::CSV (perl_code)

L<Text::Table::CSV>



=item * Text::TabularDisplay (perl_code)

L<Text::TabularDisplay>



=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 with default option:

 +-----+-----------------------------------------------------------------+-----------+--------------+---------+---------+
 | seq | name                                                            | rate      | time         | errors  | samples |
 +-----+-----------------------------------------------------------------+-----------+--------------+---------+---------+
 | 4   | {dataset=>"large (30x300)",participant=>"Text::ANSITable"}      | 2.33      | 430ms        | 0.00036 | 21      |
 | 9   | {dataset=>"large (30x300)",participant=>"Text::ASCIITable"}     | 4.03      | 248ms        | 0.00012 | 20      |
 | 14  | {dataset=>"large (30x300)",participant=>"Text::FormatTable"}    | 11.2      | 89.6ms       | 3.7e-05 | 21      |
 | 3   | {dataset=>"long (3x300)",participant=>"Text::ANSITable"}        | 20.7      | 48.3ms       | 2e-05   | 21      |
 | 44  | {dataset=>"large (30x300)",participant=>"Text::TabularDisplay"} | 27.2      | 36.8ms       | 6e-05   | 20      |
 | 8   | {dataset=>"long (3x300)",participant=>"Text::ASCIITable"}       | 40        | 25ms         | 1.5e-05 | 20      |
 | 19  | {dataset=>"large (30x300)",participant=>"Text::MarkdownTable"}  | 66.7      | 15ms         | 2.6e-05 | 20      |
 | 24  | {dataset=>"large (30x300)",participant=>"Text::Table"}          | 93.5      | 10.7ms       | 1e-05   | 20      |
 | 13  | {dataset=>"long (3x300)",participant=>"Text::FormatTable"}      | 94.1      | 10.6ms       | 9.4e-06 | 22      |
 | 2   | {dataset=>"wide (30x5)",participant=>"Text::ANSITable"}         | 98.7      | 10.1ms       | 1.4e-05 | 22      |
 | 39  | {dataset=>"large (30x300)",participant=>"Text::Table::CSV"}     | 175       | 5.72ms       | 7.4e-06 | 20      |
 | 43  | {dataset=>"long (3x300)",participant=>"Text::TabularDisplay"}   | 178       | 5.6ms        | 3.8e-06 | 20      |
 | 7   | {dataset=>"wide (30x5)",participant=>"Text::ASCIITable"}        | 187       | 5.34ms       | 5.6e-06 | 20      |
 | 34  | {dataset=>"large (30x300)",participant=>"Text::Table::Org"}     | 197       | 5.09ms       | 7.8e-06 | 20      |
 | 29  | {dataset=>"large (30x300)",participant=>"Text::Table::Tiny"}    | 239       | 4.18ms       | 9.4e-06 | 20      |
 | 18  | {dataset=>"long (3x300)",participant=>"Text::MarkdownTable"}    | 274       | 3.64ms       | 1.3e-06 | 20      |
 | 23  | {dataset=>"long (3x300)",participant=>"Text::Table"}            | 351       | 2.85ms       | 2.9e-06 | 20      |
 | 12  | {dataset=>"wide (30x5)",participant=>"Text::FormatTable"}       | 4.3e+02   | 2.3ms        | 8.1e-06 | 20      |
 | 22  | {dataset=>"wide (30x5)",participant=>"Text::Table"}             | 724       | 1.38ms       | 9.1e-07 | 20      |
 | 1   | {dataset=>"small (3x5)",participant=>"Text::ANSITable"}         | 791       | 1.26ms       | 6.1e-07 | 22      |
 | 38  | {dataset=>"long (3x300)",participant=>"Text::Table::CSV"}       | 1.2e+03   | 0.8ms        | 4e-06   | 20      |
 | 42  | {dataset=>"wide (30x5)",participant=>"Text::TabularDisplay"}    | 1.33e+03  | 0.752ms      | 8.5e-07 | 20      |
 | 33  | {dataset=>"long (3x300)",participant=>"Text::Table::Org"}       | 1.38e+03  | 0.722ms      | 4.8e-07 | 20      |
 | 28  | {dataset=>"long (3x300)",participant=>"Text::Table::Tiny"}      | 1.65e+03  | 0.607ms      | 1.3e-06 | 20      |
 | 6   | {dataset=>"small (3x5)",participant=>"Text::ASCIITable"}        | 1.73e+03  | 0.578ms      | 9.1e-07 | 20      |
 | 17  | {dataset=>"wide (30x5)",participant=>"Text::MarkdownTable"}     | 2.5e+03   | 0.4ms        | 2.7e-07 | 20      |
 | 0   | {dataset=>"tiny (1x1)",participant=>"Text::ANSITable"}          | 2.83e+03  | 0.353ms      | 2.1e-07 | 20      |
 | 11  | {dataset=>"small (3x5)",participant=>"Text::FormatTable"}       | 4.2e+03   | 0.24ms       | 1.8e-06 | 23      |
 | 21  | {dataset=>"small (3x5)",participant=>"Text::Table"}             | 5.27e+03  | 0.19ms       | 2.1e-07 | 21      |
 | 32  | {dataset=>"wide (30x5)",participant=>"Text::Table::Org"}        | 6.74e+03  | 0.148ms      | 2.1e-07 | 20      |
 | 5   | {dataset=>"tiny (1x1)",participant=>"Text::ASCIITable"}         | 7.23e+03  | 0.138ms      | 2.4e-07 | 25      |
 | 41  | {dataset=>"small (3x5)",participant=>"Text::TabularDisplay"}    | 7.9e+03   | 0.13ms       | 6.9e-07 | 20      |
 | 27  | {dataset=>"wide (30x5)",participant=>"Text::Table::Tiny"}       | 7.94e+03  | 0.126ms      | 2.1e-07 | 20      |
 | 16  | {dataset=>"small (3x5)",participant=>"Text::MarkdownTable"}     | 8.2e+03   | 0.12ms       | 5.9e-07 | 20      |
 | 37  | {dataset=>"wide (30x5)",participant=>"Text::Table::CSV"}        | 8.88e+03  | 0.113ms      | 1.6e-07 | 20      |
 | 20  | {dataset=>"tiny (1x1)",participant=>"Text::Table"}              | 1.36e+04  | 0.0734ms     | 1e-07   | 21      |
 | 15  | {dataset=>"tiny (1x1)",participant=>"Text::MarkdownTable"}      | 1.6e+04   | 0.0626ms     | 2.7e-08 | 20      |
 | 10  | {dataset=>"tiny (1x1)",participant=>"Text::FormatTable"}        | 2.026e+04 | 0.04937ms    | 1.3e-08 | 20      |
 | 40  | {dataset=>"tiny (1x1)",participant=>"Text::TabularDisplay"}     | 3.1e+04   | 0.0323ms     | 5.3e-08 | 20      |
 | 31  | {dataset=>"small (3x5)",participant=>"Text::Table::Org"}        | 3.53e+04  | 0.0283ms     | 1.3e-08 | 20      |
 | 26  | {dataset=>"small (3x5)",participant=>"Text::Table::Tiny"}       | 3.84e+04  | 0.026ms      | 1.3e-08 | 21      |
 | 36  | {dataset=>"small (3x5)",participant=>"Text::Table::CSV"}        | 5.1e+04   | 0.0196ms     | 6.7e-09 | 20      |
 | 25  | {dataset=>"tiny (1x1)",participant=>"Text::Table::Tiny"}        | 7.57e+04  | 0.0132ms     | 2e-08   | 20      |
 | 30  | {dataset=>"tiny (1x1)",participant=>"Text::Table::Org"}         | 7.72e+04  | 0.013ms      | 2e-08   | 21      |
 | 35  | {dataset=>"tiny (1x1)",participant=>"Text::Table::CSV"}         | 150218    | 0.00665701ms | 0       | 27      |
 +-----+-----------------------------------------------------------------+-----------+--------------+---------+---------+


Benchmark module startup overhead:

 +-----+----------------------+--------+-------------------+---------+---------+
 | seq | name                 | time   | mod_overhead_time | errors  | samples |
 +-----+----------------------+--------+-------------------+---------+---------+
 | 1   | Text::ANSITable      | 55ms   | 49ms              | 0.00025 | 20      |
 | 4   | Text::MarkdownTable  | 45ms   | 39ms              | 0.00019 | 20      |
 | 2   | Text::ASCIITable     | 23ms   | 17ms              | 0.00015 | 20      |
 | 5   | Text::Table          | 22ms   | 16ms              | 8.2e-05 | 20      |
 | 3   | Text::FormatTable    | 13ms   | 6.9ms             | 8.1e-05 | 20      |
 | 6   | Text::Table::Tiny    | 10.3ms | 4.27ms            | 1.1e-05 | 22      |
 | 9   | Text::TabularDisplay | 8.89ms | 2.87ms            | 2e-05   | 20      |
 | 0   | perl -e1 (baseline)  | 6ms    | 0ms               | 6.7e-05 | 20      |
 | 7   | Text::Table::Org     | 5.5ms  | -0.48ms           | 2.9e-05 | 21      |
 | 8   | Text::Table::CSV     | 5.5ms  | -0.49ms           | 3.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-TextTableModules>.

=head1 SOURCE

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

=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-TextTableModules>

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
