3 # This file specifies an array-of-hashes that define snippets of code that
4 # can be run by various measurement and profiling tools.
6 # The basic idea is that any time you add an optimisation that is intended
7 # to make a particular construct faster, then you should add that construct
10 # Under the normal test suite, the test file benchmarks.t does a basic
11 # compile and run of each of these snippets; not to test performance,
12 # but just to ensure that the code doesn't have errors.
14 # Over time, it is intended that various measurement and profiling tools
15 # will be written that can run selected (or all) snippets in various
16 # environments. These will not be run as part of a normal test suite run.
18 # It is intended that the tests in this file will be lightweight; e.g.
19 # a hash access, an empty function call, or a single regex match etc.
21 # This file is designed to be read in by 'do' (and in such a way that
22 # multiple versions of this file from different releases can be read in
23 # by a single process).
25 # The top-level array has name/hash pairs (we use an array rather than a
26 # hash so that duplicate keys can be spotted) Each name is a token that
27 # describes a particular test. Code will be compiled in the package named
28 # after the token, so it should match /^(\w|::)+$/a. It is intended that
29 # this can be used on the command line of tools to select particular
31 # In addition, the package names are arranged into an informal hierarchy
32 # whose top members are (this is subject to change):
34 # call:: subroutine and method handling
35 # expr:: expressions: e.g. $x=1, $foo{bar}[0]
36 # loop:: structural code like for, while(), etc
37 # regex:: regular expressions
38 # string:: string handling
41 # Each hash has three fields:
43 # desc is a description of the test
44 # setup is a string containing setup code
45 # code is a string containing the code to run in a loop
47 # So typically a benchmark tool might do something like
49 # eval "package $token; $setup; for (1..1000000) { $code }"
51 # Currently the only tool that uses this file is Porting/bench.pl;
52 # try C<perl Porting/bench.pl --help> for more info
56 'call::sub::3_args' => {
57 desc => 'function call with 3 local lexical vars',
58 setup => 'sub f { my ($a, $b, $c) = @_ }',
63 'expr::array::lex_1const_0' => {
64 desc => 'lexical $array[0]',
65 setup => 'my @a = (1)',
68 'expr::array::lex_1const_m1' => {
69 desc => 'lexical $array[-1]',
70 setup => 'my @a = (1)',
73 'expr::array::lex_2const' => {
74 desc => 'lexical $array[const][const]',
75 setup => 'my @a = ([1,2])',
78 'expr::array::lex_2var' => {
79 desc => 'lexical $array[$i1][$i2]',
80 setup => 'my ($i1,$i2) = (0,1); my @a = ([1,2])',
81 code => '$a[$i1][$i2]',
83 'expr::array::ref_lex_2var' => {
84 desc => 'lexical $arrayref->[$i1][$i2]',
85 setup => 'my ($i1,$i2) = (0,1); my $r = [[1,2]]',
86 code => '$r->[$i1][$i2]',
88 'expr::array::ref_lex_3const' => {
89 desc => 'lexical $arrayref->[const][const][const]',
90 setup => 'my $r = [[[1,2]]]',
91 code => '$r->[0][0][0]',
93 'expr::array::ref_expr_lex_3const' => {
94 desc => '(lexical expr)->[const][const][const]',
95 setup => 'my $r = [[[1,2]]]',
96 code => '($r||0)->[0][0][0]',
100 'expr::array::pkg_1const_0' => {
101 desc => 'package $array[0]',
105 'expr::array::pkg_1const_m1' => {
106 desc => 'package $array[-1]',
110 'expr::array::pkg_2const' => {
111 desc => 'package $array[const][const]',
112 setup => '@a = ([1,2])',
115 'expr::array::pkg_2var' => {
116 desc => 'package $array[$i1][$i2]',
117 setup => '($i1,$i2) = (0,1); @a = ([1,2])',
118 code => '$a[$i1][$i2]',
120 'expr::array::ref_pkg_2var' => {
121 desc => 'package $arrayref->[$i1][$i2]',
122 setup => '($i1,$i2) = (0,1); $r = [[1,2]]',
123 code => '$r->[$i1][$i2]',
125 'expr::array::ref_pkg_3const' => {
126 desc => 'package $arrayref->[const][const][const]',
127 setup => '$r = [[[1,2]]]',
128 code => '$r->[0][0][0]',
130 'expr::array::ref_expr_pkg_3const' => {
131 desc => '(package expr)->[const][const][const]',
132 setup => '$r = [[[1,2]]]',
133 code => '($r||0)->[0][0][0]',
137 'expr::arrayhash::lex_3var' => {
138 desc => 'lexical $h{$k1}[$i]{$k2}',
139 setup => 'my ($i, $k1, $k2) = (0,"foo","bar");'
140 . 'my %h = (foo => [ { bar => 1 } ])',
141 code => '$h{$k1}[$i]{$k2}',
143 'expr::arrayhash::pkg_3var' => {
144 desc => 'package $h{$k1}[$i]{$k2}',
145 setup => '($i, $k1, $k2) = (0,"foo","bar");'
146 . '%h = (foo => [ { bar => 1 } ])',
147 code => '$h{$k1}[$i]{$k2}',
151 'expr::assign::scalar_lex' => {
152 desc => 'lexical $x = 1',
156 'expr::assign::2list_lex' => {
157 desc => 'lexical ($x, $y) = (1, 2)',
158 setup => 'my ($x, $y)',
159 code => '($x, $y) = (1, 2)',
163 'expr::hash::lex_1const' => {
164 desc => 'lexical $hash{const}',
165 setup => 'my %h = ("foo" => 1)',
168 'expr::hash::lex_2const' => {
169 desc => 'lexical $hash{const}{const}',
170 setup => 'my %h = (foo => { bar => 1 })',
171 code => '$h{foo}{bar}',
173 'expr::hash::lex_2var' => {
174 desc => 'lexical $hash{$k1}{$k2}',
175 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 })',
176 code => '$h{$k1}{$k2}',
178 'expr::hash::ref_lex_2var' => {
179 desc => 'lexical $hashref->{$k1}{$k2}',
180 setup => 'my ($k1,$k2) = qw(foo bar); my $r = {$k1 => { $k2 => 1 }}',
181 code => '$r->{$k1}{$k2}',
183 'expr::hash::ref_lex_3const' => {
184 desc => 'lexical $hashref->{const}{const}{const}',
185 setup => 'my $r = {foo => { bar => { baz => 1 }}}',
186 code => '$r->{foo}{bar}{baz}',
188 'expr::hash::ref_expr_lex_3const' => {
189 desc => '(lexical expr)->{const}{const}{const}',
190 setup => 'my $r = {foo => { bar => { baz => 1 }}}',
191 code => '($r||0)->{foo}{bar}{baz}',
195 'expr::hash::pkg_1const' => {
196 desc => 'package $hash{const}',
197 setup => '%h = ("foo" => 1)',
200 'expr::hash::pkg_2const' => {
201 desc => 'package $hash{const}{const}',
202 setup => '%h = (foo => { bar => 1 })',
203 code => '$h{foo}{bar}',
205 'expr::hash::pkg_2var' => {
206 desc => 'package $hash{$k1}{$k2}',
207 setup => '($k1,$k2) = qw(foo bar); %h = ($k1 => { $k2 => 1 })',
208 code => '$h{$k1}{$k2}',
210 'expr::hash::ref_pkg_2var' => {
211 desc => 'package $hashref->{$k1}{$k2}',
212 setup => '($k1,$k2) = qw(foo bar); $r = {$k1 => { $k2 => 1 }}',
213 code => '$r->{$k1}{$k2}',
215 'expr::hash::ref_pkg_3const' => {
216 desc => 'package $hashref->{const}{const}{const}',
217 setup => '$r = {foo => { bar => { baz => 1 }}}',
218 code => '$r->{foo}{bar}{baz}',
220 'expr::hash::ref_expr_pkg_3const' => {
221 desc => '(package expr)->{const}{const}{const}',
222 setup => '$r = {foo => { bar => { baz => 1 }}}',
223 code => '($r||0)->{foo}{bar}{baz}',
227 'expr::hash::exists_lex_2var' => {
228 desc => 'lexical exists $hash{$k1}{$k2}',
229 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 });',
230 code => 'exists $h{$k1}{$k2}',
232 'expr::hash::delete_lex_2var' => {
233 desc => 'lexical delete $hash{$k1}{$k2}',
234 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 });',
235 code => 'delete $h{$k1}{$k2}',
239 'expr::index::utf8_position_1' => {
240 desc => 'index of a utf8 string, matching at position 1',
241 setup => 'my $x = "abc". chr(0x100); chop $x',
242 code => 'index $x, "b"',
246 # list assign, OP_AASSIGN
251 'expr::aassign::ma_empty' => {
252 desc => 'my array assigned empty',
254 code => 'my @a = ()',
256 'expr::aassign::lax_empty' => {
257 desc => 'non-empty lexical array assigned empty',
258 setup => 'my @a = 1..3;',
261 'expr::aassign::llax_empty' => {
262 desc => 'non-empty lexical var and array assigned empty',
263 setup => 'my ($x, @a) = 1..4;',
264 code => '($x, @a) = ()',
266 'expr::aassign::3m_empty' => {
267 desc => 'three my vars assigned empty',
269 code => 'my ($x,$y,$z) = ()',
271 'expr::aassign::3l_empty' => {
272 desc => 'three lexical vars assigned empty',
273 setup => 'my ($x,$y,$z)',
274 code => '($x,$y,$z) = ()',
276 'expr::aassign::pa_empty' => {
277 desc => 'package array assigned empty',
281 'expr::aassign::pax_empty' => {
282 desc => 'non-empty package array assigned empty',
283 setup => '@a = (1,2,3)',
286 'expr::aassign::3p_empty' => {
287 desc => 'three package vars assigned empty',
288 setup => '($x,$y,$z) = 1..3;',
289 code => '($x,$y,$z) = ()',
294 'expr::aassign::ma_3c' => {
295 desc => 'my array assigned 3 consts',
297 code => 'my @a = (1,2,3)',
299 'expr::aassign::lax_3c' => {
300 desc => 'non-empty lexical array assigned 3 consts',
301 setup => 'my @a = 1..3;',
302 code => '@a = (1,2,3)',
304 'expr::aassign::llax_3c' => {
305 desc => 'non-empty lexical var and array assigned 3 consts',
306 setup => 'my ($x, @a) = 1..4;',
307 code => '($x, @a) = (1,2,3)',
309 'expr::aassign::3m_3c' => {
310 desc => 'three my vars assigned 3 consts',
312 code => 'my ($x,$y,$z) = (1,2,3)',
314 'expr::aassign::3l_3c' => {
315 desc => 'three lexical vars assigned 3 consts',
316 setup => 'my ($x,$y,$z)',
317 code => '($x,$y,$z) = (1,2,3)',
319 'expr::aassign::pa_3c' => {
320 desc => 'package array assigned 3 consts',
322 code => '@a = (1,2,3)',
324 'expr::aassign::pax_3c' => {
325 desc => 'non-empty package array assigned 3 consts',
326 setup => '@a = (1,2,3)',
327 code => '@a = (1,2,3)',
329 'expr::aassign::3p_3c' => {
330 desc => 'three package vars assigned 3 consts',
331 setup => '($x,$y,$z) = 1..3;',
332 code => '($x,$y,$z) = (1,2,3)',
337 'expr::aassign::ma_la' => {
338 desc => 'my array assigned lexical array',
339 setup => 'my @init = 1..3;',
340 code => 'my @a = @init',
342 'expr::aassign::lax_la' => {
343 desc => 'non-empty lexical array assigned lexical array',
344 setup => 'my @init = 1..3; my @a = 1..3;',
345 code => '@a = @init',
347 'expr::aassign::llax_la' => {
348 desc => 'non-empty lexical var and array assigned lexical array',
349 setup => 'my @init = 1..3; my ($x, @a) = 1..4;',
350 code => '($x, @a) = @init',
352 'expr::aassign::3m_la' => {
353 desc => 'three my vars assigned lexical array',
354 setup => 'my @init = 1..3;',
355 code => 'my ($x,$y,$z) = @init',
357 'expr::aassign::3l_la' => {
358 desc => 'three lexical vars assigned lexical array',
359 setup => 'my @init = 1..3; my ($x,$y,$z)',
360 code => '($x,$y,$z) = @init',
362 'expr::aassign::pa_la' => {
363 desc => 'package array assigned lexical array',
364 setup => 'my @init = 1..3;',
365 code => '@a = @init',
367 'expr::aassign::pax_la' => {
368 desc => 'non-empty package array assigned lexical array',
369 setup => 'my @init = 1..3; @a = @init',
370 code => '@a = @init',
372 'expr::aassign::3p_la' => {
373 desc => 'three package vars assigned lexical array',
374 setup => 'my @init = 1..3; ($x,$y,$z) = 1..3;',
375 code => '($x,$y,$z) = @init',
380 'expr::aassign::ma_pa' => {
381 desc => 'my array assigned package array',
382 setup => '@init = 1..3;',
383 code => 'my @a = @init',
385 'expr::aassign::lax_pa' => {
386 desc => 'non-empty lexical array assigned package array',
387 setup => '@init = 1..3; my @a = 1..3;',
388 code => '@a = @init',
390 'expr::aassign::llax_pa' => {
391 desc => 'non-empty lexical var and array assigned package array',
392 setup => '@init = 1..3; my ($x, @a) = 1..4;',
393 code => '($x, @a) = @init',
395 'expr::aassign::3m_pa' => {
396 desc => 'three my vars assigned package array',
397 setup => '@init = 1..3;',
398 code => 'my ($x,$y,$z) = @init',
400 'expr::aassign::3l_pa' => {
401 desc => 'three lexical vars assigned package array',
402 setup => '@init = 1..3; my ($x,$y,$z)',
403 code => '($x,$y,$z) = @init',
405 'expr::aassign::pa_pa' => {
406 desc => 'package array assigned package array',
407 setup => '@init = 1..3;',
408 code => '@a = @init',
410 'expr::aassign::pax_pa' => {
411 desc => 'non-empty package array assigned package array',
412 setup => '@init = 1..3; @a = @init',
413 code => '@a = @init',
415 'expr::aassign::3p_pa' => {
416 desc => 'three package vars assigned package array',
417 setup => '@init = 1..3; ($x,$y,$z) = 1..3;',
418 code => '($x,$y,$z) = @init',
423 'expr::aassign::ma_defary' => {
424 desc => 'my array assigned @_',
425 setup => '@_ = 1..3;',
426 code => 'my @a = @_',
428 'expr::aassign::lax_defary' => {
429 desc => 'non-empty lexical array assigned @_',
430 setup => '@_ = 1..3; my @a = 1..3;',
433 'expr::aassign::llax_defary' => {
434 desc => 'non-empty lexical var and array assigned @_',
435 setup => '@_ = 1..3; my ($x, @a) = 1..4;',
436 code => '($x, @a) = @_',
438 'expr::aassign::3m_defary' => {
439 desc => 'three my vars assigned @_',
440 setup => '@_ = 1..3;',
441 code => 'my ($x,$y,$z) = @_',
443 'expr::aassign::3l_defary' => {
444 desc => 'three lexical vars assigned @_',
445 setup => '@_ = 1..3; my ($x,$y,$z)',
446 code => '($x,$y,$z) = @_',
448 'expr::aassign::pa_defary' => {
449 desc => 'package array assigned @_',
450 setup => '@_ = 1..3;',
453 'expr::aassign::pax_defary' => {
454 desc => 'non-empty package array assigned @_',
455 setup => '@_ = 1..3; @a = @_',
458 'expr::aassign::3p_defary' => {
459 desc => 'three package vars assigned @_',
460 setup => '@_ = 1..3; ($x,$y,$z) = 1..3;',
461 code => '($x,$y,$z) = @_',
465 # (....) = ($lex1,$lex2,$lex3);
467 'expr::aassign::ma_3l' => {
468 desc => 'my array assigned lexicals',
469 setup => 'my ($v1,$v2,$v3) = 1..3;',
470 code => 'my @a = ($v1,$v2,$v3)',
472 'expr::aassign::lax_3l' => {
473 desc => 'non-empty lexical array assigned lexicals',
474 setup => 'my ($v1,$v2,$v3) = 1..3; my @a = 1..3;',
475 code => '@a = ($v1,$v2,$v3)',
477 'expr::aassign::llax_3l' => {
478 desc => 'non-empty lexical var and array assigned lexicals',
479 setup => 'my ($v1,$v2,$v3) = 1..3; my ($x, @a) = 1..4;',
480 code => '($x, @a) = ($v1,$v2,$v3)',
482 'expr::aassign::3m_3l' => {
483 desc => 'three my vars assigned lexicals',
484 setup => 'my ($v1,$v2,$v3) = 1..3;',
485 code => 'my ($x,$y,$z) = ($v1,$v2,$v3)',
487 'expr::aassign::3l_3l' => {
488 desc => 'three lexical vars assigned lexicals',
489 setup => 'my ($v1,$v2,$v3) = 1..3; my ($x,$y,$z)',
490 code => '($x,$y,$z) = ($v1,$v2,$v3)',
492 'expr::aassign::pa_3l' => {
493 desc => 'package array assigned lexicals',
494 setup => 'my ($v1,$v2,$v3) = 1..3;',
495 code => '@a = ($v1,$v2,$v3)',
497 'expr::aassign::pax_3l' => {
498 desc => 'non-empty package array assigned lexicals',
499 setup => 'my ($v1,$v2,$v3) = 1..3; @a = @_',
500 code => '@a = ($v1,$v2,$v3)',
502 'expr::aassign::3p_3l' => {
503 desc => 'three package vars assigned lexicals',
504 setup => 'my ($v1,$v2,$v3) = 1..3; ($x,$y,$z) = 1..3;',
505 code => '($x,$y,$z) = ($v1,$v2,$v3)',
509 # (....) = ($pkg1,$pkg2,$pkg3);
511 'expr::aassign::ma_3p' => {
512 desc => 'my array assigned 3 package vars',
513 setup => '($v1,$v2,$v3) = 1..3;',
514 code => 'my @a = ($v1,$v2,$v3)',
516 'expr::aassign::lax_3p' => {
517 desc => 'non-empty lexical array assigned 3 package vars',
518 setup => '($v1,$v2,$v3) = 1..3; my @a = 1..3;',
519 code => '@a = ($v1,$v2,$v3)',
521 'expr::aassign::llax_3p' => {
522 desc => 'non-empty lexical var and array assigned 3 package vars',
523 setup => '($v1,$v2,$v3) = 1..3; my ($x, @a) = 1..4;',
524 code => '($x, @a) = ($v1,$v2,$v3)',
526 'expr::aassign::3m_3p' => {
527 desc => 'three my vars assigned 3 package vars',
528 setup => '($v1,$v2,$v3) = 1..3;',
529 code => 'my ($x,$y,$z) = ($v1,$v2,$v3)',
531 'expr::aassign::3l_3p' => {
532 desc => 'three lexical vars assigned 3 package vars',
533 setup => '($v1,$v2,$v3) = 1..3; my ($x,$y,$z)',
534 code => '($x,$y,$z) = ($v1,$v2,$v3)',
536 'expr::aassign::pa_3p' => {
537 desc => 'package array assigned 3 package vars',
538 setup => '($v1,$v2,$v3) = 1..3;',
539 code => '@a = ($v1,$v2,$v3)',
541 'expr::aassign::pax_3p' => {
542 desc => 'non-empty package array assigned 3 package vars',
543 setup => '($v1,$v2,$v3) = 1..3; @a = @_',
544 code => '@a = ($v1,$v2,$v3)',
546 'expr::aassign::3p_3p' => {
547 desc => 'three package vars assigned 3 package vars',
548 setup => '($v1,$v2,$v3) = 1..3; ($x,$y,$z) = 1..3;',
549 code => '($x,$y,$z) = ($v1,$v2,$v3)',
553 # (....) = (1,2,$shared);
555 'expr::aassign::llax_2c1s' => {
556 desc => 'non-empty lexical var and array assigned 2 consts and 1 shared var',
557 setup => 'my ($x, @a) = 1..4;',
558 code => '($x, @a) = (1,2,$x)',
560 'expr::aassign::3l_2c1s' => {
561 desc => 'three lexical vars assigned 2 consts and 1 shared var',
562 setup => 'my ($x,$y,$z) = 1..3;',
563 code => '($x,$y,$z) = (1,2,$x)',
565 'expr::aassign::3p_2c1s' => {
566 desc => 'three package vars assigned 2 consts and 1 shared var',
567 setup => '($x,$y,$z) = 1..3;',
568 code => '($x,$y,$z) = (1,2,$x)',
574 'expr::aassign::2l_swap' => {
575 desc => 'swap two lexical vars',
576 setup => 'my ($a,$b) = (1,2)',
577 code => '($a,$b) = ($b,$a)',
579 'expr::aassign::2p_swap' => {
580 desc => 'swap two package vars',
581 setup => '($a,$b) = (1,2)',
582 code => '($a,$b) = ($b,$a)',
584 'expr::aassign::2laelem_swap' => {
585 desc => 'swap two lexical vars',
586 setup => 'my @a = (1,2)',
587 code => '($a[0],$a[1]) = ($a[1],$a[0])',
592 'expr::aassign::5l_4l1s' => {
593 desc => 'long list of lexical vars, 1 shared',
594 setup => 'my ($a,$b,$c,$d,$e) = 1..5',
595 code => '($a,$b,$c,$d,$e) = ($a,$a,$c,$d,$e)',
598 'expr::aassign::5p_4p1s' => {
599 desc => 'long list of package vars, 1 shared',
600 setup => '($a,$b,$c,$d,$e) = 1..5',
601 code => '($a,$b,$c,$d,$e) = ($a,$a,$c,$d,$e)',
603 'expr::aassign::5l_defary' => {
604 desc => 'long list of lexical vars to assign @_ to',
605 setup => '@_ = 1..5',
606 code => 'my ($a,$b,$c,$d,$e) = @_',
608 'expr::aassign::5l1la_defary' => {
609 desc => 'long list of lexical vars plus long slurp to assign @_ to',
610 setup => '@_ = 1..20',
611 code => 'my ($a,$b,$c,$d,$e,@rest) = @_',
613 'expr::aassign::1l_2l' => {
614 desc => 'single lexical LHS',
615 setup => 'my $x = 1;',
616 code => '(undef,$x) = ($x,$x)',
618 'expr::aassign::2l_1l' => {
619 desc => 'single lexical RHS',
620 setup => 'my $x = 1;',
621 code => '($x,$x) = ($x)',
623 'expr::aassign::2l_1ul' => {
624 desc => 'undef and single lexical RHS',
625 setup => 'my $x = 1;',
626 code => '($x,$x) = (undef, $x)',