#! /usr/bin/perl
# PODNAME: benchmark-perlformance
# ABSTRACT: Frontend for Benchmark::Perl::Formance

use Benchmark::Perl::Formance;

my $pf = Benchmark::Perl::Formance->new;

my $results = $pf->run;
$pf->print_results($results);

__END__

=pod

=encoding UTF-8

=head1 NAME

benchmark-perlformance - Frontend for Benchmark::Perl::Formance

=head1 SYNOPSIS

Usage:

  $ benchmark-perlformance
  $ benchmark-perlformance --plugins=SpamAssassin,Fib,Rx
  $ benchmark-perlformance --plugins=SpamAssassin,Fib,Rx -q
  $ benchmark-perlformance --plugins=SpamAssassin,Fib,Rx -v
  $ benchmark-perlformance --plugins=SpamAssassin,Fib,Rx -vv -ccccc

To provide configuration, general and plugin specific, you can use the
C<-D> option to define key/value pairs:

  $ benchmark-perlformance -DShootout_fasta_n=5500  [...]

Plugins usually follow the convention that the options are prefixed
with the plugin name, like in the example it means the config value
C<n> used by the plugin C<Shootout::fasta>.

=head1 ABOUT

This is the frontend commandline tool for starting the performance
benchmark runs.

After running it prints out the results which you can take to compare
them to runs with other Perl versions, other architectures, different
compile time configuration or on different machines.

=head1 OPTIONS

There are some options available.

=over 4

=item --help

=item -h

prints out a help page.

=item --plugins=SpamAssassin,Fib,Rx

Use only a particular list of sub benchmarks. The comma-separated list
refers to C<Benchmark::Perl::Formance::Plugin::*> respectively.

If you provide C<--plugins=ALL> then all known plugins will be tried.

If you do not provide the C<--plugins> option then a default list of
"mostly harmless" plugins is used which should work with the same
dependencies of Benchmark::Perl::Formance itself (currently: C<DPath>,
C<Fib>, C<FibOO>, C<Mem>, C<Prime>, C<Rx>, C<Shootout::>{C<fasta>,
C<regexdna>, C<binarytrees>, C<revcomp>, C<nbody>, C<spectralnorm>}).

=item --outstyle=summary

This activates a condensed tabular output. Default since v0.10.

=item --outstyle=json

This activates JSON formatted output containing meta information.

=item --outstyle=yaml

This activates YAML formatted output containing meta information.

=item --outstyle=yamlish

Similar to C<--outstyle=yaml>, except the produced YAML is actually
the lightweight variant YAMLish produced by L<Data::YAML::Writer|Data::YAML::Writer>,
which can easily be embedded into TAP.

=item --benchmarkanything

This option produces benchmarks result entries following the
L<BenchmarkAnything::Schema|BenchmarkAnything schema>.

Implicitely enables C<--outstyle=json> (unless you specify
--outstyle=yaml/yamlish), C<-cccc> (extensive config info), C<-p>
(platform info).

=item --benchmarkanything-report

This reports the results to a L<BenchmarkAnything
store|BenchmarkAnything::Storage::Frontend::Lib>, as configured in
your BenchmarkAnything config ($BENCHMARKANYTHING_CONFIGFILE or
C<~/.benchmarkanything.cfg>).

Implicitely enables C<--benchmarkanything>, C<--outstyle=json>,
C<-cccc> (extensive config info), C<-p> (platform info).

=item --outfile=FILE

Write results into FILE. If FILE can not be opened then it prints to STDOUT.

=item --fastmode

If this is set then some plugins try to scale down the stress to take
less time (with less useful results, of course). Mostly for easier
development.

=item --stabilize-cpu

Runs an external utility script
(C<benchmark-perlformance-set-stable-system>) which stabilizes the
system to get less deviation on multiple runs.

The system is stabilized using:

=over 4

=item * Disable address space randomization (ASLR)

See L<https://wiki.ubuntu.com/Security/Features>

=item * Set maximum frequency of all cpus to minimum frequency

Therefore the system can't scale down further unexpectedly, e.g. when
it gets hot.

=item * Drop caches

See L<http://linux-mm.org/Drop_Caches>.

=item * Classical disk sync

Flush file system buffers, see C<man 1 sync>.

=back

The external utility script is called via C<sudo> - please configure
your sudo in advance to suit your needs, e.g. to not ask for
password. An alternative approach is to run
C<benchmark-perlformance-set-stable-system lo> once when your system
boots, like from C</etc/init.d/> (and run your cpu slow all the time,
obviously).

B<Be careful>: maybe the cpu is not restored perfectly after a run,
e.g., due to crashes during the benchmarking, or the values are not
the very same. This could make your next results without
C<--stabilize-cpu> inconclusive. Reboot your system to ensure a clean
state or use C<--stabilize-cpu> all the time.

=item --version

Print Benchmark::Perl::Formance version.
In conjunction with C<-v> it prints out all available
plugins with version.

=item --verbose

=item -v

=item -vv

=item -vvv

=item -vvvv

=item -vvvvv

Increases the verbosity level during the run of the
benchmarks. Default is only print the result (and maybe some output
from external tools).

To increase the number of keys from your Perl Config that are included
in the result use one or more -c options.

Please note that only one single -v is not enough to see errors that
occur when trying to load a plugin. They are only marked as
"skipped". Use -vv to see the error message; -vvv for progress
information; -vvvv or more should be used for debugging info.

=item -q

Be quiet; do not output results.

=item --showconfig

=item -c

Gives you the most basic information like Perl version, operating
system name and architecture, i.e., C<perlpath>, C<version>,
C<archname>, C<archname64>, C<osvers>.

=item -cc

Adds C<gccversion>, C<gnulibc_version>, C<usemymalloc>,
C<config_args>, C<optimize>.

=item -ccc

Adds C<ccflags>, C<ccname>, C<cccdlflags>, C<ccdlflags>, C<cppflags>, C<nm_so_opt>.

=item -cccc

Adds about 40 more keys from Perl's %Config hash - everything that
sounds like it could either influence performance between different
hardware, configurations, and compilers, or interesting meta
information around that.

=item -ccccc

Includes all info from Perl's %Config hash.

=item -p

Includes platform info via Devel::Platform::Info

(Users who want to greet the 80s combine it this way: C<-cccp>. :-))

=item --tapdescription="some description"

When given together with C<--outstyle=yamlish> this will prepend the
YAMLish with a TAP line

  ok some description

This makes it easier for wrappers to embed the output into TAP which
otherwise need to differentiate between output (verbose and other) and
the YAMLish.

=item --indent=2

This indents the output of C<--outstyle=yamlish> by some spaces (2 in
the example). Together with C<--tapdescription> it makes an TAP v13
style structured diagnostics block which can, for instance, be
evaluated using L<TAP::DOM>.

=item --useforks

By setting this you can activate the C<forks> drop-in replacement for
threads.

See
L<Benchmark::Perl::Formance::Plugin::Threads|Benchmark::Perl::Formance::Plugin::Threads>.

=item -Dkey=value

With this you can configure some plugins by defining key/value pairs.

=back

=head1 ENVIRONMENT VARIABLES

There are some options available.

=over 4

=item PERLFORMANCE_SALEARN

See L<Benchmark::Perl::Formance::Plugin::SpamAssassin|Benchmark::Perl::Formance::Plugin::SpamAssassin>. Contains
the path to the "sa-learn" executable.

=item PERLFORMANCE_THREADCOUNT

See
L<Benchmark::Perl::Formance::Plugin::Threads|Benchmark::Perl::Formance::Plugin::Threads>. Use
this many count of threads. Default is 16.

=back

=head1 PLUGINS

Please read the documentation for the used plugins, as they might accept
special configuration, usually via C<-Dkey=value> options.

=over 4

=item L<Benchmark::Perl::Formance::Plugin::SpamAssassin|Benchmark::Perl::Formance::Plugin::SpamAssassin>

Macro benchmark. Run sa-learn learning tool from SpamAssassin, which stresses string, regex and data structures operations.

=item L<Benchmark::Perl::Formance::Plugin::Mem|Benchmark::Perl::Formance::Plugin::Mem>

Micro benchmarks. Stress memory operations.

=item L<Benchmark::Perl::Formance::Plugin::Prime|Benchmark::Perl::Formance::Plugin::Prime>

Micro benchmarks. Prime numbers.

=item L<Benchmark::Perl::Formance::Plugin::DPath|Benchmark::Perl::Formance::Plugin::DPath>

Macro benchmark. Use DPath to stress lookup, traversing and copying data structures.

=item L<Benchmark::Perl::Formance::Plugin::Rx|Benchmark::Perl::Formance::Plugin::Rx>

Micro benchmarks. Regular expressions, basic functions and pathological regex stressing.

=item L<Benchmark::Perl::Formance::Plugin::RxCmp|Benchmark::Perl::Formance::Plugin::RxCmp>

Micro benchmarks. Compare differnet regex engines (pluggable since Perl 5.10).

=item L<Benchmark::Perl::Formance::Plugin::RegexpCommonTS|Benchmark::Perl::Formance::Plugin::RegexpCommonTS>

Micro benchmarks. Stress regexes by running the Regexp::Common testsuite.

=item L<Benchmark::Perl::Formance::Plugin::MatrixReal|Benchmark::Perl::Formance::Plugin::MatrixReal>

Micro benchmarks. Pure Perl matrix operations.

=item L<Benchmark::Perl::Formance::Plugin::Fib|Benchmark::Perl::Formance::Plugin::Fib>

Micro benchmarks. Fibonnacci numbers to stress recursion and function calls.

=item L<Benchmark::Perl::Formance::Plugin::FibOO|Benchmark::Perl::Formance::Plugin::FibOO>

Micro benchmarks. Fibonnacci numbers to stress recursion and method calls, with plain Perl OO.

=item L<Benchmark::Perl::Formance::Plugin::FibOOSig|Benchmark::Perl::Formance::Plugin::FibOOSig>

Micro benchmarks. Fibonnacci numbers to stress recursion and method calls, with plain Perl OO using 5.20 signatures.

=item L<Benchmark::Perl::Formance::Plugin::FibMoose|Benchmark::Perl::Formance::Plugin::FibMoose>

Micro benchmarks. Fibonnacci numbers to stress recursion and method calls, with Moose.

=item L<Benchmark::Perl::Formance::Plugin::FibMouse|Benchmark::Perl::Formance::Plugin::FibMouse>

Micro benchmarks. Fibonnacci numbers to stress recursion and method calls, with Mouse.

=item L<Benchmark::Perl::Formance::Plugin::FibMXDeclare|Benchmark::Perl::Formance::Plugin::FibMXDeclare>

Micro benchmarks. Fibonnacci numbers to stress recursion and method calls, with MooseX::Declare.

=item L<Benchmark::Perl::Formance::Plugin::Threads|Benchmark::Perl::Formance::Plugin::Threads>

Micro benchmarks. Stress thread handling.

=item L<Benchmark::Perl::Formance::Plugin::ThreadsShared|Benchmark::Perl::Formance::Plugin::ThreadsShared>

Micro benchmarks. Stress thread handling with shared variables.

=item L<Benchmark::Perl::Formance::Plugin::PerlCritic|Benchmark::Perl::Formance::Plugin::PerlCritic>

Macro benchmarks. Run PerlCritic on itself.

=item L<Benchmark::Perl::Formance::Plugin::Shootout|Benchmark::Perl::Formance::Plugin::Shootout>

Micro benchmarks. Runs some Perl benchmarks from the Language Shootout on alioth.debian.org.

=item L<Benchmark::Perl::Formance::Plugin::P6STD|Benchmark::Perl::Formance::Plugin::P6STD>

Macro benchmarks. Stress using Perl6/Perl5 tools around Perl6 STD.pm.

=back

=head1 AUTHOR

Steffen Schwigon <ss5@renormalist.net>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2021 by Steffen Schwigon.

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
