package Bencher::Scenario::TextTableModules;

our $DATE = '2016-10-19'; # DATE
our $VERSION = '0.07'; # 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::TinyColor',
            code => sub {
                my ($table) = @_;
                Text::Table::TinyColor::table(rows=>$table, header_row=>1);
            },
        },
        {
            module => 'Text::Table::TinyColorWide',
            code => sub {
                my ($table) = @_;
                Text::Table::TinyColorWide::table(rows=>$table, header_row=>1);
            },
        },
        {
            module => 'Text::Table::TinyWide',
            code => sub {
                my ($table) = @_;
                Text::Table::TinyWide::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 - Benchmark modules that generate text table

=head1 VERSION

This document describes version 0.07 of Bencher::Scenario::TextTableModules (from Perl distribution Bencher-Scenario-TextTableModules), released on 2016-10-19.

=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 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 BENCHMARKED MODULES

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

L<Text::ANSITable> 0.48

L<Text::ASCIITable> 0.20

L<Text::FormatTable> 1.03

L<Text::MarkdownTable> 0.3.1

L<Text::Table> 1.131

L<Text::Table::Tiny> 0.04

L<Text::Table::TinyColor> 0.002

L<Text::Table::TinyColorWide> 0.001

L<Text::Table::TinyWide> 0.001

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::TinyColor (perl_code)

L<Text::Table::TinyColor>



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

L<Text::Table::TinyColorWide>



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

L<Text::Table::TinyWide>



=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 BENCHMARK DATASETS

=over

=item * tiny (1x1)

=item * small (3x5)

=item * wide (30x5)

=item * long (3x300)

=item * large (30x300)

=back

=head1 SAMPLE BENCHMARK RESULTS

Run on: perl: I<< v5.24.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 options (C<< bencher -m TextTableModules >>):

 #table1#
 {dataset=>"large (30x300)"}
 +----------------------------+-----------+-----------+------------+-----------+---------+
 | participant                | rate (/s) | time (ms) | vs_slowest |  errors   | samples |
 +----------------------------+-----------+-----------+------------+-----------+---------+
 | Text::ANSITable            |       2.1 |     480   |       1    |   0.00054 |      20 |
 | Text::ASCIITable           |       4.5 |     220   |       2.1  |   0.00033 |      21 |
 | Text::Table::TinyColorWide |      10   |      99.9 |       4.76 | 9.9e-05   |      21 |
 | Text::FormatTable          |      12   |      83   |       5.7  |   0.00016 |      20 |
 | Text::Table::TinyWide      |      15   |      66   |       7.2  | 6.8e-05   |      20 |
 | Text::TabularDisplay       |      29   |      35   |      14    | 3.6e-05   |      20 |
 | Text::Table::TinyColor     |      44   |      23   |      21    | 2.5e-05   |      20 |
 | Text::MarkdownTable        |      71   |      14   |      34    | 8.5e-05   |      21 |
 | Text::Table                |      98.6 |      10.1 |      46.9  | 9.6e-06   |      20 |
 | Text::Table::CSV           |     160   |       6.1 |      78    | 4.4e-05   |      20 |
 | Text::Table::Org           |     220   |       4.6 |     100    | 7.4e-06   |      20 |
 | Text::Table::Tiny          |     250   |       4   |     120    | 6.9e-06   |      20 |
 +----------------------------+-----------+-----------+------------+-----------+---------+

 #table2#
 {dataset=>"long (3x300)"}
 +----------------------------+-----------+-----------+------------+---------+---------+
 | participant                | rate (/s) | time (ms) | vs_slowest |  errors | samples |
 +----------------------------+-----------+-----------+------------+---------+---------+
 | Text::ANSITable            |      19.1 |    52.3   |       1    | 4.5e-05 |      20 |
 | Text::ASCIITable           |      45.3 |    22.1   |       2.37 |   2e-05 |      20 |
 | Text::Table::TinyColorWide |      94.9 |    10.5   |       4.97 | 4.5e-06 |      20 |
 | Text::FormatTable          |     102   |     9.8   |       5.34 | 9.7e-06 |      22 |
 | Text::Table::TinyWide      |     143   |     7     |       7.47 | 6.7e-06 |      20 |
 | Text::TabularDisplay       |     190   |     5.2   |      10    | 5.2e-06 |      21 |
 | Text::MarkdownTable        |     310   |     3.2   |      16    | 9.4e-06 |      21 |
 | Text::Table                |     390   |     2.6   |      20    | 2.9e-06 |      20 |
 | Text::Table::TinyColor     |     390   |     2.5   |      21    | 5.2e-06 |      20 |
 | Text::Table::CSV           |    1300   |     0.77  |      68    | 1.8e-06 |      21 |
 | Text::Table::Org           |    1590   |     0.628 |      83.3  | 4.8e-07 |      20 |
 | Text::Table::Tiny          |    1820   |     0.549 |      95.2  | 2.1e-07 |      20 |
 +----------------------------+-----------+-----------+------------+---------+---------+

 #table3#
 {dataset=>"small (3x5)"}
 +----------------------------+-----------+-----------+------------+---------+---------+
 | participant                | rate (/s) | time (μs) | vs_slowest |  errors | samples |
 +----------------------------+-----------+-----------+------------+---------+---------+
 | Text::ANSITable            |    770    |  1300     |    1       | 2.7e-06 |      21 |
 | Text::ASCIITable           |   1940    |   514     |    2.54    | 2.1e-07 |      20 |
 | Text::Table::TinyColorWide |   4400    |   230     |    5.7     | 4.3e-07 |      20 |
 | Text::FormatTable          |   4460    |   224     |    5.83    | 1.6e-07 |      20 |
 | Text::Table                |   5728.87 |   174.554 |    7.48586 | 1.6e-10 |      21 |
 | Text::Table::TinyWide      |   6120    |   163     |    8       | 5.3e-08 |      20 |
 | Text::TabularDisplay       |   8340    |   120     |   10.9     | 5.3e-08 |      20 |
 | Text::MarkdownTable        |   9000    |   110     |   12       | 1.6e-07 |      20 |
 | Text::Table::TinyColor     |  15300    |    65.3   |   20       | 2.7e-08 |      20 |
 | Text::Table::Org           |  39000    |    25     |   52       | 9.8e-08 |      21 |
 | Text::Table::Tiny          |  41200    |    24.3   |   53.8     |   2e-08 |      20 |
 | Text::Table::CSV           |  52000    |    19     |   68       | 3.3e-08 |      20 |
 +----------------------------+-----------+-----------+------------+---------+---------+

 #table4#
 {dataset=>"tiny (1x1)"}
 +----------------------------+-----------+-----------+------------+---------+---------+
 | participant                | rate (/s) | time (μs) | vs_slowest |  errors | samples |
 +----------------------------+-----------+-----------+------------+---------+---------+
 | Text::ANSITable            |      3200 |     320   |       1    | 4.3e-07 |      20 |
 | Text::ASCIITable           |      8000 |     120   |       2.5  | 2.1e-07 |      20 |
 | Text::Table                |     15100 |      66.1 |       4.78 | 2.7e-08 |      20 |
 | Text::MarkdownTable        |     17900 |      55.8 |       5.67 | 2.5e-08 |      23 |
 | Text::FormatTable          |     21400 |      46.7 |       6.78 | 1.3e-08 |      20 |
 | Text::Table::TinyColorWide |     26000 |      38   |       8.2  | 5.3e-08 |      20 |
 | Text::Table::TinyWide      |     32000 |      31   |      10    | 5.3e-08 |      20 |
 | Text::TabularDisplay       |     33000 |      30   |      10    | 5.2e-08 |      21 |
 | Text::Table::TinyColor     |     54000 |      19   |      17    | 2.7e-08 |      20 |
 | Text::Table::Tiny          |     80900 |      12.4 |      25.6  |   1e-08 |      20 |
 | Text::Table::Org           |     86000 |      12   |      27    | 1.3e-08 |      20 |
 | Text::Table::CSV           |    170000 |       5.9 |      53    | 6.5e-09 |      21 |
 +----------------------------+-----------+-----------+------------+---------+---------+

 #table5#
 {dataset=>"wide (30x5)"}
 +----------------------------+-----------+-----------+------------+---------+---------+
 | participant                | rate (/s) | time (ms) | vs_slowest |  errors | samples |
 +----------------------------+-----------+-----------+------------+---------+---------+
 | Text::ANSITable            |      94.6 |    10.6   |       1    | 1.1e-05 |      20 |
 | Text::ASCIITable           |     210   |     4.8   |       2.2  | 1.1e-05 |      20 |
 | Text::FormatTable          |     480   |     2.1   |       5.1  | 3.2e-06 |      21 |
 | Text::Table::TinyColorWide |     490   |     2     |       5.2  | 2.2e-06 |      20 |
 | Text::Table::TinyWide      |     710   |     1.4   |       7.5  | 2.6e-06 |      24 |
 | Text::Table                |     801   |     1.25  |       8.47 | 1.2e-06 |      22 |
 | Text::TabularDisplay       |    1400   |     0.72  |      15    | 1.3e-06 |      20 |
 | Text::Table::TinyColor     |    2100   |     0.48  |      22    |   9e-07 |      28 |
 | Text::MarkdownTable        |    2680   |     0.372 |      28.4  | 2.6e-07 |      21 |
 | Text::Table::Org           |    7200   |     0.14  |      76    | 2.7e-07 |      20 |
 | Text::Table::Tiny          |    8120   |     0.123 |      85.9  | 4.2e-08 |      33 |
 | Text::Table::CSV           |    8900   |     0.112 |      94.1  | 5.2e-08 |      21 |
 +----------------------------+-----------+-----------+------------+---------+---------+


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

 #table6#
 +----------------------------+-----------+------------------------+------------+-----------+---------+
 | participant                | time (ms) | mod_overhead_time (ms) | vs_slowest |  errors   | samples |
 +----------------------------+-----------+------------------------+------------+-----------+---------+
 | Text::ANSITable            |      59   |    53                  |        1   |   0.00019 |      21 |
 | Text::MarkdownTable        |      48   |    42                  |        1.2 |   0.00023 |      20 |
 | Text::Table::TinyColorWide |      47   |    41                  |        1.2 |   0.00044 |      22 |
 | Text::Table::TinyWide      |      42   |    36                  |        1.4 |   0.00011 |      21 |
 | Text::ASCIITable           |      23   |    17                  |        2.6 |   0.00011 |      20 |
 | Text::Table                |      23   |    17                  |        2.6 |   0.00014 |      20 |
 | Text::Table::TinyColor     |      13   |     7                  |        4.5 | 2.7e-05   |      20 |
 | Text::FormatTable          |      13   |     7                  |        4.5 | 4.4e-05   |      20 |
 | Text::Table::Tiny          |      11   |     5                  |        5.4 | 3.2e-05   |      20 |
 | Text::TabularDisplay       |       9.3 |     3.3                |        6.3 | 3.3e-05   |      20 |
 | Text::Table::Org           |       6.5 |     0.5                |        9.1 | 1.8e-05   |      20 |
 | perl -e1 (baseline)        |       6   |     0                  |       10   | 9.4e-05   |      21 |
 | Text::Table::CSV           |       5.9 |    -0.0999999999999996 |       10   | 4.5e-05   |      20 |
 +----------------------------+-----------+------------------------+------------+-----------+---------+

=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
