#!perl
# This file specifies an array-of-hashes that define snippets of code that
# can be run by various measurement and profiling tools.
#
# The basic idea is that any time you add an optimisation that is intended
# to make a particular construct faster, then you should add that construct
# to this file.
#
# Under the normal test suite, the test file benchmarks.t does a basic
# compile and run of each of these snippets; not to test performance,
# but just to ensure that the code doesn't have errors.
#
# Over time, it is intended that various measurement and profiling tools
# will be written that can run selected (or all) snippets in various
# environments. These will not be run as part of a normal test suite run.
#
# It is intended that the tests in this file will be lightweight; e.g.
# a hash access, an empty function call, or a single regex match etc.
#
# This file is designed to be read in by 'do' (and in such a way that
# multiple versions of this file from different releases can be read in
# by a single process).
#
# The top-level array has name/hash pairs (we use an array rather than a
# hash so that duplicate keys can be spotted) Each name is a token that
# describes a particular test. Code will be compiled in the package named
# after the token, so it should match /^(\w|::)+$/a. It is intended that
# this can be used on the command line of tools to select particular
# tests.
# In addition, the package names are arranged into an informal hierarchy
# whose top members are (this is subject to change):
#
# call:: subroutine and method handling
# expr:: expressions: e.g. $x=1, $foo{bar}[0]
# loop:: structural code like for, while(), etc
# regex:: regular expressions
# string:: string handling
#
#
# Each hash has three fields:
#
# desc is a description of the test
# setup is a string containing setup code
# code is a string containing the code to run in a loop
#
# So typically a benchmark tool might do something like
#
# eval "package $token; $setup; for (1..1000000) { $code }"
#
# Currently the only tool that uses this file is Porting/bench.pl;
# try C<perl Porting/bench.pl --help> for more info
[
'call::sub::3_args' => {
desc => 'function call with 3 local lexical vars',
setup => 'sub f { my ($a, $b, $c) = @_ }',
code => 'f(1,2,3)',
},
'expr::array::lex_1const_0' => {
desc => 'lexical $array[0]',
setup => 'my @a = (1)',
code => '$a[0]',
},
'expr::array::lex_1const_m1' => {
desc => 'lexical $array[-1]',
setup => 'my @a = (1)',
code => '$a[-1]',
},
'expr::array::lex_2const' => {
desc => 'lexical $array[const][const]',
setup => 'my @a = ([1,2])',
code => '$a[0][1]',
},
'expr::array::lex_2var' => {
desc => 'lexical $array[$i1][$i2]',
setup => 'my ($i1,$i2) = (0,1); my @a = ([1,2])',
code => '$a[$i1][$i2]',
},
'expr::array::ref_lex_2var' => {
desc => 'lexical $arrayref->[$i1][$i2]',
setup => 'my ($i1,$i2) = (0,1); my $r = [[1,2]]',
code => '$r->[$i1][$i2]',
},
'expr::array::ref_lex_3const' => {
desc => 'lexical $arrayref->[const][const][const]',
setup => 'my $r = [[[1,2]]]',
code => '$r->[0][0][0]',
},
'expr::array::ref_expr_lex_3const' => {
desc => '(lexical expr)->[const][const][const]',
setup => 'my $r = [[[1,2]]]',
code => '($r//0)->[0][0][0]',
},
'expr::array::pkg_1const_0' => {
desc => 'package $array[0]',
setup => 'our @a = (1)',
code => '$a[0]',
},
'expr::array::pkg_1const_m1' => {
desc => 'package $array[-1]',
setup => 'our @a = (1)',
code => '$a[-1]',
},
'expr::array::pkg_2const' => {
desc => 'package $array[const][const]',
setup => 'our @a = ([1,2])',
code => '$a[0][1]',
},
'expr::array::pkg_2var' => {
desc => 'package $array[$i1][$i2]',
setup => 'our ($i1,$i2) = (0,1); our @a = ([1,2])',
code => '$a[$i1][$i2]',
},
'expr::array::ref_pkg_2var' => {
desc => 'package $arrayref->[$i1][$i2]',
setup => 'our ($i1,$i2) = (0,1); our $r = [[1,2]]',
code => '$r->[$i1][$i2]',
},
'expr::array::ref_pkg_3const' => {
desc => 'package $arrayref->[const][const][const]',
setup => 'our $r = [[[1,2]]]',
code => '$r->[0][0][0]',
},
'expr::array::ref_expr_pkg_3const' => {
desc => '(package expr)->[const][const][const]',
setup => 'our $r = [[[1,2]]]',
code => '($r//0)->[0][0][0]',
},
'expr::arrayhash::lex_3var' => {
desc => 'lexical $h{$k1}[$i]{$k2}',
setup => 'my ($i, $k1, $k2) = (0,"foo","bar");'
. 'my %h = (foo => [ { bar => 1 } ])',
code => '$h{$k1}[$i]{$k2}',
},
'expr::arrayhash::pkg_3var' => {
desc => 'package $h{$k1}[$i]{$k2}',
setup => 'our ($i, $k1, $k2) = (0,"foo","bar");'
. 'our %h = (foo => [ { bar => 1 } ])',
code => '$h{$k1}[$i]{$k2}',
},
'expr::assign::scalar_lex' => {
desc => 'lexical $x = 1',
setup => 'my $x',
code => '$x = 1',
},
'expr::assign::2list_lex' => {
desc => 'lexical ($x, $y) = (1, 2)',
setup => 'my ($x, $y)',
code => '($x, $y) = (1, 2)',
},
'expr::hash::lex_1const' => {
desc => 'lexical $hash{const}',
setup => 'my %h = ("foo" => 1)',
code => '$h{foo}',
},
'expr::hash::lex_2const' => {
desc => 'lexical $hash{const}{const}',
setup => 'my %h = (foo => { bar => 1 })',
code => '$h{foo}{bar}',
},
'expr::hash::lex_2var' => {
desc => 'lexical $hash{$k1}{$k2}',
setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 })',
code => '$h{$k1}{$k2}',
},
'expr::hash::ref_lex_2var' => {
desc => 'lexical $hashref->{$k1}{$k2}',
setup => 'my ($k1,$k2) = qw(foo bar); my $r = {$k1 => { $k2 => 1 }}',
code => '$r->{$k1}{$k2}',
},
'expr::hash::ref_lex_3const' => {
desc => 'lexical $hashref->{const}{const}{const}',
setup => 'my $r = {foo => { bar => { baz => 1 }}}',
code => '$r->{foo}{bar}{baz}',
},
'expr::hash::ref_expr_lex_3const' => {
desc => '(lexical expr)->{const}{const}{const}',
setup => 'my $r = {foo => { bar => { baz => 1 }}}',
code => '($r//0)->{foo}{bar}{baz}',
},
'expr::hash::pkg_1const' => {
desc => 'package $hash{const}',
setup => 'our %h = ("foo" => 1)',
code => '$h{foo}',
},
'expr::hash::pkg_2const' => {
desc => 'package $hash{const}{const}',
setup => 'our %h = (foo => { bar => 1 })',
code => '$h{foo}{bar}',
},
'expr::hash::pkg_2var' => {
desc => 'package $hash{$k1}{$k2}',
setup => 'our ($k1,$k2) = qw(foo bar); our %h = ($k1 => { $k2 => 1 })',
code => '$h{$k1}{$k2}',
},
'expr::hash::ref_pkg_2var' => {
desc => 'package $hashref->{$k1}{$k2}',
setup => 'our ($k1,$k2) = qw(foo bar); our $r = {$k1 => { $k2 => 1 }}',
code => '$r->{$k1}{$k2}',
},
'expr::hash::ref_pkg_3const' => {
desc => 'package $hashref->{const}{const}{const}',
setup => 'our $r = {foo => { bar => { baz => 1 }}}',
code => '$r->{foo}{bar}{baz}',
},
'expr::hash::ref_expr_pkg_3const' => {
desc => '(package expr)->{const}{const}{const}',
setup => 'our $r = {foo => { bar => { baz => 1 }}}',
code => '($r//0)->{foo}{bar}{baz}',
},
'expr::hash::exists_lex_2var' => {
desc => 'lexical exists $hash{$k1}{$k2}',
setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 });',
code => 'exists $h{$k1}{$k2}',
},
'expr::hash::delete_lex_2var' => {
desc => 'lexical delete $hash{$k1}{$k2}',
setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 });',
code => 'delete $h{$k1}{$k2}',
},
'expr::index::utf8_position_1' => {
desc => 'index of a utf8 string, matching at position 1',
setup => 'utf8::upgrade my $x = "abc"',
code => 'index $x, "b"',
},
];