Benchmark-MCE

 view release on metacpan or  search on metacpan

lib/Benchmark/MCE.pm  view on Meta::CPAN


Unless C<$keep_outliers> is true, the overall scalability is an average after droping
Benchmarks that are non-scaling outliers (over 2*stdev less than the mean).

The result hash return looks like this:

 %scal = (
   bench_name => $bench_avg_scalability,
    ...
   _total => $total_avg_scalability
 );


=head2 C<suite_calc>

 my ($stats, $stats_multi, $scal) = suite_calc(\%suite_run_options, $keep_outliers?);

Convenience function that combines 3 calls, L</suite_run> with C<threads=E<gt>1>,
L</suite_run> with C<threads=E<gt>system_identity(1)> and L</calc_scalability> with
the results of those two, returning hashrefs with the results of all three calls.

For single-core systems (or when C<system_identity(1)> does not return E<gt> 1)
only C<$stats> will be returned.

You can override the C<system_identity(1)> call and run the multi-thread bench with
a custom number of threads by passing C<threads =E<gt> [count]>.

=head1 BENCHMARK FUNCTIONS

The benchmark functions will be called with two parameters that you can choose to
take advantage of.
The first one is what you define as either the C<$quick_arg> or C<$normal_arg>,
with the intention being to have a way to run a C<quick> mode that lets you test with
smaller workloads. The second argument will be an integer that's the chunk number
from L<MCE::Loop> - it will be 1 for the call on the first thread, 2 from the second
thread etc, so your function may track which worker/chunk is running.

The function may return a string, usually a checksum, that will be checked against
the (optional) C<$expected> parameter to show a Pass/Fail (useful for verifying
correctness, stress testing, etc.).

Example:

  use Benchmark::MCE;
  use Math::Trig qw/:great_circle :pi/;

  sub great_circle {
    my $size  = shift || 1;  # Optionally have an argument that scales the workload
    my $chunk = shift;       # Optionally use the chunk number
    my $dist = 0;
    $dist +=
      great_circle_distance(rand(pi), rand(2 * pi), rand(pi), rand(2 * pi))
        for 1 .. $size;
    return $dist; # Returning a value is optional for the Pass/Fail functionality
  }

  my %stats = suite_run({
      bench => { 'Math::Trig' =>  # A unique name for the benchmark
        [
        \&great_circle,      # Reference to bench function
        '3144042.81433949',  # Reference output - determines Pass/Fail (optional)
        5.5,                 # Seconds to complete in normal mode for score = 1000 (optional)
        1000000,             # Argument to pass for quick mode (optional)
        5000000              # Argument to pass for normal mode (optional)
        ]},
    }
  );

=head1 STDOUT / QUIET MODE

Normally function calls will print results to C<STDOUT> as well as return them.
You can suppress STDOUT by setting:

  $Benchmark::MCE::QUIET = 1;

=head1 NOTES

The framework uses a monotonic timer for non-Windows systems with at least v1.9764
of C<Time::HiRes> (C<$Benchmark::MCE::MONO_CLOCK> will be true).

=head1 AUTHOR

Dimitrios Kechagias, C<< <dkechag at cpan.org> >>

=head1 BUGS

Please report any bugs or feature requests on L<GitHub|https://github.com/SpareRoom/Benchmark-MCE>.

=head1 GIT

L<https://github.com/SpareRoom/Benchmark-MCE>

=head1 LICENSE AND COPYRIGHT

Copyright (c) 2025-2026 Dimitrios Kechagias and SpareRoom.

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

sub system_identity {
    my ($physical, $cores, $ncpu) = System::CPU::get_cpu;
    $ncpu ||= 1;
    return $ncpu if @_;

    local $^O = 'linux' if $^O =~ /android/;
    my $info  = System::Info->sysinfo_hash;
    my $osn   = $info->{distro} || $info->{os} || $^O;
    my $model = System::CPU::get_name || '';
    my $arch  = System::CPU::get_arch || '';
    $arch = " ($arch)" if $arch;
    _print("--------------- Software ---------------\n",_package_ver(),"\n");
    _printf(
        "Perl $^V (%sthreads, %smulti)\n",
        $Config{usethreads}      ? '' : 'no ',
        $Config{usemultiplicity} ? '' : 'no '
    );
    _print("OS: $osn\n--------------- Hardware ---------------\n");
    _print("CPU type: $model$arch\n");
    _print("CPUs: $ncpu");



( run in 1.876 second using v1.01-cache-2.11-cpan-39bf76dae61 )