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::empty' => {
57 desc => 'function call with no args or body',
61 'call::sub::amp_empty' => {
62 desc => '&foo function call with no args or body',
63 setup => 'sub f { }; @_ = ();',
66 'call::sub::args3' => {
67 desc => 'function call with 3 local lexical vars',
68 setup => 'sub f { my ($a, $b, $c) = @_; 1 }',
71 'call::sub::args2_ret1' => {
72 desc => 'function call with 2 local lex vars and 1 return value',
73 setup => 'my $x; sub f { my ($a, $b) = @_; $a+$b }',
74 code => '$x = f(1,2)',
76 'call::sub::args2_ret1temp' => {
77 desc => 'function call with 2 local lex vars and 1 return TEMP value',
78 setup => 'my $x; sub f { my ($a, $b) = @_; \$a }',
79 code => '$x = f(1,2)',
81 'call::sub::args3_ret3' => {
82 desc => 'function call with 3 local lex vars and 3 return values',
83 setup => 'my @a; sub f { my ($a, $b, $c) = @_; $a+$b, $c, 1 }',
84 code => '@a = f(1,2,3)',
86 'call::sub::args3_ret3str' => {
87 desc => 'function call with 3 local lex vars and 3 string return values',
88 setup => 'my @a; sub f { my ($a, $b, $c) = @_; my @s = ("aa","bb","cc"); @s }',
89 code => '@a = f(1,2,3)',
91 'call::sub::args3_ret3temp' => {
92 desc => 'function call with 3 local lex vars and 3 TEMP return values',
93 setup => 'my @a; sub f { my ($a, $b, $c) = @_; 1..3 }',
94 code => '@a = f(1,2,3)',
96 'call::sub::recursive' => {
97 desc => 'basic recursive function call',
98 setup => 'my $x; sub f { my ($i) = @_; $i > 0 ? $i + f($i-1) : 0 }',
102 'call::goto::empty' => {
103 desc => 'goto &funtion with no args or body',
104 setup => 'sub f { goto &g } sub g {}',
107 'call::goto::args3' => {
108 desc => 'goto &funtion with 3 local lexical vars',
109 setup => 'sub f { goto &g } sub g { my ($a, $b, $c) = @_ }',
114 'expr::array::lex_1const_0' => {
115 desc => 'lexical $array[0]',
116 setup => 'my @a = (1)',
119 'expr::array::lex_1const_m1' => {
120 desc => 'lexical $array[-1]',
121 setup => 'my @a = (1)',
124 'expr::array::lex_2const' => {
125 desc => 'lexical $array[const][const]',
126 setup => 'my @a = ([1,2])',
129 'expr::array::lex_2var' => {
130 desc => 'lexical $array[$i1][$i2]',
131 setup => 'my ($i1,$i2) = (0,1); my @a = ([1,2])',
132 code => '$a[$i1][$i2]',
134 'expr::array::ref_lex_2var' => {
135 desc => 'lexical $arrayref->[$i1][$i2]',
136 setup => 'my ($i1,$i2) = (0,1); my $r = [[1,2]]',
137 code => '$r->[$i1][$i2]',
139 'expr::array::ref_lex_3const' => {
140 desc => 'lexical $arrayref->[const][const][const]',
141 setup => 'my $r = [[[1,2]]]',
142 code => '$r->[0][0][0]',
144 'expr::array::ref_expr_lex_3const' => {
145 desc => '(lexical expr)->[const][const][const]',
146 setup => 'my $r = [[[1,2]]]',
147 code => '($r||0)->[0][0][0]',
151 'expr::array::pkg_1const_0' => {
152 desc => 'package $array[0]',
156 'expr::array::pkg_1const_m1' => {
157 desc => 'package $array[-1]',
161 'expr::array::pkg_2const' => {
162 desc => 'package $array[const][const]',
163 setup => '@a = ([1,2])',
166 'expr::array::pkg_2var' => {
167 desc => 'package $array[$i1][$i2]',
168 setup => '($i1,$i2) = (0,1); @a = ([1,2])',
169 code => '$a[$i1][$i2]',
171 'expr::array::ref_pkg_2var' => {
172 desc => 'package $arrayref->[$i1][$i2]',
173 setup => '($i1,$i2) = (0,1); $r = [[1,2]]',
174 code => '$r->[$i1][$i2]',
176 'expr::array::ref_pkg_3const' => {
177 desc => 'package $arrayref->[const][const][const]',
178 setup => '$r = [[[1,2]]]',
179 code => '$r->[0][0][0]',
181 'expr::array::ref_expr_pkg_3const' => {
182 desc => '(package expr)->[const][const][const]',
183 setup => '$r = [[[1,2]]]',
184 code => '($r||0)->[0][0][0]',
188 'expr::arrayhash::lex_3var' => {
189 desc => 'lexical $h{$k1}[$i]{$k2}',
190 setup => 'my ($i, $k1, $k2) = (0,"foo","bar");'
191 . 'my %h = (foo => [ { bar => 1 } ])',
192 code => '$h{$k1}[$i]{$k2}',
194 'expr::arrayhash::pkg_3var' => {
195 desc => 'package $h{$k1}[$i]{$k2}',
196 setup => '($i, $k1, $k2) = (0,"foo","bar");'
197 . '%h = (foo => [ { bar => 1 } ])',
198 code => '$h{$k1}[$i]{$k2}',
202 'expr::assign::scalar_lex_int' => {
203 desc => 'lexical $x = 1',
207 'expr::assign::scalar_lex_str' => {
208 desc => 'lexical $x = "abc"',
210 code => '$x = "abc"',
212 'expr::assign::scalar_lex_strint' => {
213 desc => 'lexical $x = 1 where $x was previously a string',
214 setup => 'my $x = "abc"',
217 'expr::assign::scalar_lex_intstr' => {
218 desc => 'lexical $x = "abc" where $x was previously an int',
219 setup => 'my $x = 1;',
220 code => '$x = "abc"',
222 'expr::assign::2list_lex' => {
223 desc => 'lexical ($x, $y) = (1, 2)',
224 setup => 'my ($x, $y)',
225 code => '($x, $y) = (1, 2)',
229 'expr::hash::lex_1const' => {
230 desc => 'lexical $hash{const}',
231 setup => 'my %h = ("foo" => 1)',
234 'expr::hash::lex_2const' => {
235 desc => 'lexical $hash{const}{const}',
236 setup => 'my %h = (foo => { bar => 1 })',
237 code => '$h{foo}{bar}',
239 'expr::hash::lex_2var' => {
240 desc => 'lexical $hash{$k1}{$k2}',
241 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 })',
242 code => '$h{$k1}{$k2}',
244 'expr::hash::ref_lex_2var' => {
245 desc => 'lexical $hashref->{$k1}{$k2}',
246 setup => 'my ($k1,$k2) = qw(foo bar); my $r = {$k1 => { $k2 => 1 }}',
247 code => '$r->{$k1}{$k2}',
249 'expr::hash::ref_lex_3const' => {
250 desc => 'lexical $hashref->{const}{const}{const}',
251 setup => 'my $r = {foo => { bar => { baz => 1 }}}',
252 code => '$r->{foo}{bar}{baz}',
254 'expr::hash::ref_expr_lex_3const' => {
255 desc => '(lexical expr)->{const}{const}{const}',
256 setup => 'my $r = {foo => { bar => { baz => 1 }}}',
257 code => '($r||0)->{foo}{bar}{baz}',
261 'expr::hash::pkg_1const' => {
262 desc => 'package $hash{const}',
263 setup => '%h = ("foo" => 1)',
266 'expr::hash::pkg_2const' => {
267 desc => 'package $hash{const}{const}',
268 setup => '%h = (foo => { bar => 1 })',
269 code => '$h{foo}{bar}',
271 'expr::hash::pkg_2var' => {
272 desc => 'package $hash{$k1}{$k2}',
273 setup => '($k1,$k2) = qw(foo bar); %h = ($k1 => { $k2 => 1 })',
274 code => '$h{$k1}{$k2}',
276 'expr::hash::ref_pkg_2var' => {
277 desc => 'package $hashref->{$k1}{$k2}',
278 setup => '($k1,$k2) = qw(foo bar); $r = {$k1 => { $k2 => 1 }}',
279 code => '$r->{$k1}{$k2}',
281 'expr::hash::ref_pkg_3const' => {
282 desc => 'package $hashref->{const}{const}{const}',
283 setup => '$r = {foo => { bar => { baz => 1 }}}',
284 code => '$r->{foo}{bar}{baz}',
286 'expr::hash::ref_expr_pkg_3const' => {
287 desc => '(package expr)->{const}{const}{const}',
288 setup => '$r = {foo => { bar => { baz => 1 }}}',
289 code => '($r||0)->{foo}{bar}{baz}',
293 'expr::hash::exists_lex_2var' => {
294 desc => 'lexical exists $hash{$k1}{$k2}',
295 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 });',
296 code => 'exists $h{$k1}{$k2}',
298 'expr::hash::delete_lex_2var' => {
299 desc => 'lexical delete $hash{$k1}{$k2}',
300 setup => 'my ($k1,$k2) = qw(foo bar); my %h = ($k1 => { $k2 => 1 });',
301 code => 'delete $h{$k1}{$k2}',
305 # using a const string as second arg to index triggers using FBM.
306 # the FBM matcher special-cases 1,2-byte strings.
308 'expr::index::short_const1' => {
309 desc => 'index of a short string against a 1 char const substr',
310 setup => 'my $x = "aaaab"',
311 code => 'index $x, "b"',
313 'expr::index::long_const1' => {
314 desc => 'index of a long string against a 1 char const substr',
315 setup => 'my $x = "a" x 1000 . "b"',
316 code => 'index $x, "b"',
318 'expr::index::short_const2aabc_bc' => {
319 desc => 'index of a short string against a 2 char const substr',
320 setup => 'my $x = "aaaabc"',
321 code => 'index $x, "bc"',
323 'expr::index::long_const2aabc_bc' => {
324 desc => 'index of a long string against a 2 char const substr',
325 setup => 'my $x = "a" x 1000 . "bc"',
326 code => 'index $x, "bc"',
328 'expr::index::long_const2aa_ab' => {
329 desc => 'index of a long string aaa.. against const substr "ab"',
330 setup => 'my $x = "a" x 1000',
331 code => 'index $x, "ab"',
333 'expr::index::long_const2bb_ab' => {
334 desc => 'index of a long string bbb.. against const substr "ab"',
335 setup => 'my $x = "b" x 1000',
336 code => 'index $x, "ab"',
338 'expr::index::long_const2aa_bb' => {
339 desc => 'index of a long string aaa.. against const substr "bb"',
340 setup => 'my $x = "a" x 1000',
341 code => 'index $x, "bb"',
343 # this one is designed to be pathological
344 'expr::index::long_const2ab_aa' => {
345 desc => 'index of a long string abab.. against const substr "aa"',
346 setup => 'my $x = "ab" x 500',
347 code => 'index $x, "aa"',
349 # near misses with gaps, 1st letter
350 'expr::index::long_const2aaxx_xy' => {
351 desc => 'index of a long string with "xx"s against const substr "xy"',
352 setup => 'my $x = "aaaaaaaaxx" x 100',
353 code => 'index $x, "xy"',
355 # near misses with gaps, 2nd letter
356 'expr::index::long_const2aayy_xy' => {
357 desc => 'index of a long string with "yy"s against const substr "xy"',
358 setup => 'my $x = "aaaaaaaayy" x 100',
359 code => 'index $x, "xy"',
361 # near misses with gaps, duplicate letter
362 'expr::index::long_const2aaxy_xx' => {
363 desc => 'index of a long string with "xy"s against const substr "xx"',
364 setup => 'my $x = "aaaaaaaaxy" x 100',
365 code => 'index $x, "xx"',
367 # alternating near misses with gaps
368 'expr::index::long_const2aaxxaayy_xy' => {
369 desc => 'index of a long string with "xx/yy"s against const substr "xy"',
370 setup => 'my $x = "aaaaaaaaxxbbbbbbbbyy" x 50',
371 code => 'index $x, "xy"',
373 'expr::index::short_const3aabcd_bcd' => {
374 desc => 'index of a short string against a 3 char const substr',
375 setup => 'my $x = "aaaabcd"',
376 code => 'index $x, "bcd"',
378 'expr::index::long_const3aabcd_bcd' => {
379 desc => 'index of a long string against a 3 char const substr',
380 setup => 'my $x = "a" x 1000 . "bcd"',
381 code => 'index $x, "bcd"',
383 'expr::index::long_const3ab_abc' => {
384 desc => 'index of a long string of "ab"s against a 3 char const substr "abc"',
385 setup => 'my $x = "ab" x 500',
386 code => 'index $x, "abc"',
388 'expr::index::long_const3bc_abc' => {
389 desc => 'index of a long string of "bc"s against a 3 char const substr "abc"',
390 setup => 'my $x = "bc" x 500',
391 code => 'index $x, "abc"',
393 'expr::index::utf8_position_1' => {
394 desc => 'index of a utf8 string, matching at position 1',
395 setup => 'my $x = "abc". chr(0x100); chop $x',
396 code => 'index $x, "b"',
400 # list assign, OP_AASSIGN
405 'expr::aassign::ma_empty' => {
406 desc => 'my array assigned empty',
408 code => 'my @a = ()',
410 'expr::aassign::lax_empty' => {
411 desc => 'non-empty lexical array assigned empty',
412 setup => 'my @a = 1..3;',
415 'expr::aassign::llax_empty' => {
416 desc => 'non-empty lexical var and array assigned empty',
417 setup => 'my ($x, @a) = 1..4;',
418 code => '($x, @a) = ()',
420 'expr::aassign::3m_empty' => {
421 desc => 'three my vars assigned empty',
423 code => 'my ($x,$y,$z) = ()',
425 'expr::aassign::3l_empty' => {
426 desc => 'three lexical vars assigned empty',
427 setup => 'my ($x,$y,$z)',
428 code => '($x,$y,$z) = ()',
430 'expr::aassign::pa_empty' => {
431 desc => 'package array assigned empty',
435 'expr::aassign::pax_empty' => {
436 desc => 'non-empty package array assigned empty',
437 setup => '@a = (1,2,3)',
440 'expr::aassign::3p_empty' => {
441 desc => 'three package vars assigned empty',
442 setup => '($x,$y,$z) = 1..3;',
443 code => '($x,$y,$z) = ()',
448 'expr::aassign::ma_3c' => {
449 desc => 'my array assigned 3 consts',
451 code => 'my @a = (1,2,3)',
453 'expr::aassign::lax_3c' => {
454 desc => 'non-empty lexical array assigned 3 consts',
455 setup => 'my @a = 1..3;',
456 code => '@a = (1,2,3)',
458 'expr::aassign::llax_3c' => {
459 desc => 'non-empty lexical var and array assigned 3 consts',
460 setup => 'my ($x, @a) = 1..4;',
461 code => '($x, @a) = (1,2,3)',
463 'expr::aassign::3m_3c' => {
464 desc => 'three my vars assigned 3 consts',
466 code => 'my ($x,$y,$z) = (1,2,3)',
468 'expr::aassign::3l_3c' => {
469 desc => 'three lexical vars assigned 3 consts',
470 setup => 'my ($x,$y,$z)',
471 code => '($x,$y,$z) = (1,2,3)',
473 'expr::aassign::pa_3c' => {
474 desc => 'package array assigned 3 consts',
476 code => '@a = (1,2,3)',
478 'expr::aassign::pax_3c' => {
479 desc => 'non-empty package array assigned 3 consts',
480 setup => '@a = (1,2,3)',
481 code => '@a = (1,2,3)',
483 'expr::aassign::3p_3c' => {
484 desc => 'three package vars assigned 3 consts',
485 setup => '($x,$y,$z) = 1..3;',
486 code => '($x,$y,$z) = (1,2,3)',
491 'expr::aassign::ma_la' => {
492 desc => 'my array assigned lexical array',
493 setup => 'my @init = 1..3;',
494 code => 'my @a = @init',
496 'expr::aassign::lax_la' => {
497 desc => 'non-empty lexical array assigned lexical array',
498 setup => 'my @init = 1..3; my @a = 1..3;',
499 code => '@a = @init',
501 'expr::aassign::llax_la' => {
502 desc => 'non-empty lexical var and array assigned lexical array',
503 setup => 'my @init = 1..3; my ($x, @a) = 1..4;',
504 code => '($x, @a) = @init',
506 'expr::aassign::3m_la' => {
507 desc => 'three my vars assigned lexical array',
508 setup => 'my @init = 1..3;',
509 code => 'my ($x,$y,$z) = @init',
511 'expr::aassign::3l_la' => {
512 desc => 'three lexical vars assigned lexical array',
513 setup => 'my @init = 1..3; my ($x,$y,$z)',
514 code => '($x,$y,$z) = @init',
516 'expr::aassign::pa_la' => {
517 desc => 'package array assigned lexical array',
518 setup => 'my @init = 1..3;',
519 code => '@a = @init',
521 'expr::aassign::pax_la' => {
522 desc => 'non-empty package array assigned lexical array',
523 setup => 'my @init = 1..3; @a = @init',
524 code => '@a = @init',
526 'expr::aassign::3p_la' => {
527 desc => 'three package vars assigned lexical array',
528 setup => 'my @init = 1..3; ($x,$y,$z) = 1..3;',
529 code => '($x,$y,$z) = @init',
534 'expr::aassign::ma_pa' => {
535 desc => 'my array assigned package array',
536 setup => '@init = 1..3;',
537 code => 'my @a = @init',
539 'expr::aassign::lax_pa' => {
540 desc => 'non-empty lexical array assigned package array',
541 setup => '@init = 1..3; my @a = 1..3;',
542 code => '@a = @init',
544 'expr::aassign::llax_pa' => {
545 desc => 'non-empty lexical var and array assigned package array',
546 setup => '@init = 1..3; my ($x, @a) = 1..4;',
547 code => '($x, @a) = @init',
549 'expr::aassign::3m_pa' => {
550 desc => 'three my vars assigned package array',
551 setup => '@init = 1..3;',
552 code => 'my ($x,$y,$z) = @init',
554 'expr::aassign::3l_pa' => {
555 desc => 'three lexical vars assigned package array',
556 setup => '@init = 1..3; my ($x,$y,$z)',
557 code => '($x,$y,$z) = @init',
559 'expr::aassign::pa_pa' => {
560 desc => 'package array assigned package array',
561 setup => '@init = 1..3;',
562 code => '@a = @init',
564 'expr::aassign::pax_pa' => {
565 desc => 'non-empty package array assigned package array',
566 setup => '@init = 1..3; @a = @init',
567 code => '@a = @init',
569 'expr::aassign::3p_pa' => {
570 desc => 'three package vars assigned package array',
571 setup => '@init = 1..3; ($x,$y,$z) = 1..3;',
572 code => '($x,$y,$z) = @init',
577 'expr::aassign::ma_defary' => {
578 desc => 'my array assigned @_',
579 setup => '@_ = 1..3;',
580 code => 'my @a = @_',
582 'expr::aassign::lax_defary' => {
583 desc => 'non-empty lexical array assigned @_',
584 setup => '@_ = 1..3; my @a = 1..3;',
587 'expr::aassign::llax_defary' => {
588 desc => 'non-empty lexical var and array assigned @_',
589 setup => '@_ = 1..3; my ($x, @a) = 1..4;',
590 code => '($x, @a) = @_',
592 'expr::aassign::3m_defary' => {
593 desc => 'three my vars assigned @_',
594 setup => '@_ = 1..3;',
595 code => 'my ($x,$y,$z) = @_',
597 'expr::aassign::3l_defary' => {
598 desc => 'three lexical vars assigned @_',
599 setup => '@_ = 1..3; my ($x,$y,$z)',
600 code => '($x,$y,$z) = @_',
602 'expr::aassign::pa_defary' => {
603 desc => 'package array assigned @_',
604 setup => '@_ = 1..3;',
607 'expr::aassign::pax_defary' => {
608 desc => 'non-empty package array assigned @_',
609 setup => '@_ = 1..3; @a = @_',
612 'expr::aassign::3p_defary' => {
613 desc => 'three package vars assigned @_',
614 setup => '@_ = 1..3; ($x,$y,$z) = 1..3;',
615 code => '($x,$y,$z) = @_',
619 # (....) = ($lex1,$lex2,$lex3);
621 'expr::aassign::ma_3l' => {
622 desc => 'my array assigned lexicals',
623 setup => 'my ($v1,$v2,$v3) = 1..3;',
624 code => 'my @a = ($v1,$v2,$v3)',
626 'expr::aassign::lax_3l' => {
627 desc => 'non-empty lexical array assigned lexicals',
628 setup => 'my ($v1,$v2,$v3) = 1..3; my @a = 1..3;',
629 code => '@a = ($v1,$v2,$v3)',
631 'expr::aassign::llax_3l' => {
632 desc => 'non-empty lexical var and array assigned lexicals',
633 setup => 'my ($v1,$v2,$v3) = 1..3; my ($x, @a) = 1..4;',
634 code => '($x, @a) = ($v1,$v2,$v3)',
636 'expr::aassign::3m_3l' => {
637 desc => 'three my vars assigned lexicals',
638 setup => 'my ($v1,$v2,$v3) = 1..3;',
639 code => 'my ($x,$y,$z) = ($v1,$v2,$v3)',
641 'expr::aassign::3l_3l' => {
642 desc => 'three lexical vars assigned lexicals',
643 setup => 'my ($v1,$v2,$v3) = 1..3; my ($x,$y,$z)',
644 code => '($x,$y,$z) = ($v1,$v2,$v3)',
646 'expr::aassign::pa_3l' => {
647 desc => 'package array assigned lexicals',
648 setup => 'my ($v1,$v2,$v3) = 1..3;',
649 code => '@a = ($v1,$v2,$v3)',
651 'expr::aassign::pax_3l' => {
652 desc => 'non-empty package array assigned lexicals',
653 setup => 'my ($v1,$v2,$v3) = 1..3; @a = @_',
654 code => '@a = ($v1,$v2,$v3)',
656 'expr::aassign::3p_3l' => {
657 desc => 'three package vars assigned lexicals',
658 setup => 'my ($v1,$v2,$v3) = 1..3; ($x,$y,$z) = 1..3;',
659 code => '($x,$y,$z) = ($v1,$v2,$v3)',
663 # (....) = ($pkg1,$pkg2,$pkg3);
665 'expr::aassign::ma_3p' => {
666 desc => 'my array assigned 3 package vars',
667 setup => '($v1,$v2,$v3) = 1..3;',
668 code => 'my @a = ($v1,$v2,$v3)',
670 'expr::aassign::lax_3p' => {
671 desc => 'non-empty lexical array assigned 3 package vars',
672 setup => '($v1,$v2,$v3) = 1..3; my @a = 1..3;',
673 code => '@a = ($v1,$v2,$v3)',
675 'expr::aassign::llax_3p' => {
676 desc => 'non-empty lexical var and array assigned 3 package vars',
677 setup => '($v1,$v2,$v3) = 1..3; my ($x, @a) = 1..4;',
678 code => '($x, @a) = ($v1,$v2,$v3)',
680 'expr::aassign::3m_3p' => {
681 desc => 'three my vars assigned 3 package vars',
682 setup => '($v1,$v2,$v3) = 1..3;',
683 code => 'my ($x,$y,$z) = ($v1,$v2,$v3)',
685 'expr::aassign::3l_3p' => {
686 desc => 'three lexical vars assigned 3 package vars',
687 setup => '($v1,$v2,$v3) = 1..3; my ($x,$y,$z)',
688 code => '($x,$y,$z) = ($v1,$v2,$v3)',
690 'expr::aassign::pa_3p' => {
691 desc => 'package array assigned 3 package vars',
692 setup => '($v1,$v2,$v3) = 1..3;',
693 code => '@a = ($v1,$v2,$v3)',
695 'expr::aassign::pax_3p' => {
696 desc => 'non-empty package array assigned 3 package vars',
697 setup => '($v1,$v2,$v3) = 1..3; @a = @_',
698 code => '@a = ($v1,$v2,$v3)',
700 'expr::aassign::3p_3p' => {
701 desc => 'three package vars assigned 3 package vars',
702 setup => '($v1,$v2,$v3) = 1..3; ($x,$y,$z) = 1..3;',
703 code => '($x,$y,$z) = ($v1,$v2,$v3)',
707 # (....) = (1,2,$shared);
709 'expr::aassign::llax_2c1s' => {
710 desc => 'non-empty lexical var and array assigned 2 consts and 1 shared var',
711 setup => 'my ($x, @a) = 1..4;',
712 code => '($x, @a) = (1,2,$x)',
714 'expr::aassign::3l_2c1s' => {
715 desc => 'three lexical vars assigned 2 consts and 1 shared var',
716 setup => 'my ($x,$y,$z) = 1..3;',
717 code => '($x,$y,$z) = (1,2,$x)',
719 'expr::aassign::3p_2c1s' => {
720 desc => 'three package vars assigned 2 consts and 1 shared var',
721 setup => '($x,$y,$z) = 1..3;',
722 code => '($x,$y,$z) = (1,2,$x)',
728 'expr::aassign::2l_swap' => {
729 desc => 'swap two lexical vars',
730 setup => 'my ($a,$b) = (1,2)',
731 code => '($a,$b) = ($b,$a)',
733 'expr::aassign::2p_swap' => {
734 desc => 'swap two package vars',
735 setup => '($a,$b) = (1,2)',
736 code => '($a,$b) = ($b,$a)',
738 'expr::aassign::2laelem_swap' => {
739 desc => 'swap two lexical vars',
740 setup => 'my @a = (1,2)',
741 code => '($a[0],$a[1]) = ($a[1],$a[0])',
746 'expr::aassign::5l_4l1s' => {
747 desc => 'long list of lexical vars, 1 shared',
748 setup => 'my ($a,$b,$c,$d,$e) = 1..5',
749 code => '($a,$b,$c,$d,$e) = ($a,$a,$c,$d,$e)',
752 'expr::aassign::5p_4p1s' => {
753 desc => 'long list of package vars, 1 shared',
754 setup => '($a,$b,$c,$d,$e) = 1..5',
755 code => '($a,$b,$c,$d,$e) = ($a,$a,$c,$d,$e)',
757 'expr::aassign::5l_defary' => {
758 desc => 'long list of lexical vars to assign @_ to',
759 setup => '@_ = 1..5',
760 code => 'my ($a,$b,$c,$d,$e) = @_',
762 'expr::aassign::5l1la_defary' => {
763 desc => 'long list of lexical vars plus long slurp to assign @_ to',
764 setup => '@_ = 1..20',
765 code => 'my ($a,$b,$c,$d,$e,@rest) = @_',
767 'expr::aassign::1l_2l' => {
768 desc => 'single lexical LHS',
769 setup => 'my $x = 1;',
770 code => '(undef,$x) = ($x,$x)',
772 'expr::aassign::2l_1l' => {
773 desc => 'single lexical RHS',
774 setup => 'my $x = 1;',
775 code => '($x,$x) = ($x)',
777 'expr::aassign::2l_1ul' => {
778 desc => 'undef and single lexical RHS',
779 setup => 'my $x = 1;',
780 code => '($x,$x) = (undef, $x)',
784 'expr::arith::add_lex_ii' => {
785 desc => 'add two integers and assign to a lexical var',
786 setup => 'my ($x,$y,$z) = 1..3;',
787 code => '$z = $x + $y',
789 'expr::arith::add_pkg_ii' => {
790 desc => 'add two integers and assign to a package var',
791 setup => 'my ($x,$y) = 1..2; $z = 3;',
792 code => '$z = $x + $y',
794 'expr::arith::add_lex_nn' => {
795 desc => 'add two NVs and assign to a lexical var',
796 setup => 'my ($x,$y,$z) = (1.1, 2.2, 3.3);',
797 code => '$z = $x + $y',
799 'expr::arith::add_pkg_nn' => {
800 desc => 'add two NVs and assign to a package var',
801 setup => 'my ($x,$y); ($x,$y,$z) = (1.1, 2.2, 3.3);',
802 code => '$z = $x + $y',
804 'expr::arith::add_lex_ni' => {
805 desc => 'add an int and an NV and assign to a lexical var',
806 setup => 'my ($x,$y,$z) = (1, 2.2, 3.3);',
807 code => '$z = $x + $y',
809 'expr::arith::add_pkg_ni' => {
810 desc => 'add an int and an NV and assign to a package var',
811 setup => 'my ($x,$y); ($x,$y,$z) = (1, 2.2, 3.3);',
812 code => '$z = $x + $y',
815 'expr::arith::sub_lex_ii' => {
816 desc => 'subtract two integers and assign to a lexical var',
817 setup => 'my ($x,$y,$z) = 1..3;',
818 code => '$z = $x - $y',
820 'expr::arith::sub_pkg_ii' => {
821 desc => 'subtract two integers and assign to a package var',
822 setup => 'my ($x,$y) = 1..2; $z = 3;',
823 code => '$z = $x - $y',
825 'expr::arith::sub_lex_nn' => {
826 desc => 'subtract two NVs and assign to a lexical var',
827 setup => 'my ($x,$y,$z) = (1.1, 2.2, 3.3);',
828 code => '$z = $x - $y',
830 'expr::arith::sub_pkg_nn' => {
831 desc => 'subtract two NVs and assign to a package var',
832 setup => 'my ($x,$y); ($x,$y,$z) = (1.1, 2.2, 3.3);',
833 code => '$z = $x - $y',
835 'expr::arith::sub_lex_ni' => {
836 desc => 'subtract an int and an NV and assign to a lexical var',
837 setup => 'my ($x,$y,$z) = (1, 2.2, 3.3);',
838 code => '$z = $x - $y',
840 'expr::arith::sub_pkg_ni' => {
841 desc => 'subtract an int and an NV and assign to a package var',
842 setup => 'my ($x,$y); ($x,$y,$z) = (1, 2.2, 3.3);',
843 code => '$z = $x - $y',
846 'expr::arith::mult_lex_ii' => {
847 desc => 'multiply two integers and assign to a lexical var',
848 setup => 'my ($x,$y,$z) = 1..3;',
849 code => '$z = $x * $y',
851 'expr::arith::mult_pkg_ii' => {
852 desc => 'multiply two integers and assign to a package var',
853 setup => 'my ($x,$y) = 1..2; $z = 3;',
854 code => '$z = $x * $y',
856 'expr::arith::mult_lex_nn' => {
857 desc => 'multiply two NVs and assign to a lexical var',
858 setup => 'my ($x,$y,$z) = (1.1, 2.2, 3.3);',
859 code => '$z = $x * $y',
861 'expr::arith::mult_pkg_nn' => {
862 desc => 'multiply two NVs and assign to a package var',
863 setup => 'my ($x,$y); ($x,$y,$z) = (1.1, 2.2, 3.3);',
864 code => '$z = $x * $y',
866 'expr::arith::mult_lex_ni' => {
867 desc => 'multiply an int and an NV and assign to a lexical var',
868 setup => 'my ($x,$y,$z) = (1, 2.2, 3.3);',
869 code => '$z = $x * $y',
871 'expr::arith::mult_pkg_ni' => {
872 desc => 'multiply an int and an NV and assign to a package var',
873 setup => 'my ($x,$y); ($x,$y,$z) = (1, 2.2, 3.3);',
874 code => '$z = $x * $y',
877 'expr::arith::preinc' => {
879 setup => 'my $x = 1;',
882 'expr::arith::predec' => {
884 setup => 'my $x = 1;',
887 'expr::arith::postinc' => {
889 setup => 'my $x = 1; my $y',
890 code => '$y = $x++', # scalar context so not optimised to ++$x
892 'expr::arith::postdec' => {
894 setup => 'my $x = 1; my $y',
895 code => '$y = $x--', # scalar context so not optimised to --$x
899 desc => 'empty basic loop',
905 desc => 'basic do block',
906 setup => 'my $x; my $y = 2;',
907 code => '$x = do {1; $y}', # the ';' stops the do being optimised
910 'loop::for::my_range1' => {
911 desc => 'empty for loop with my var and 1 integer range',
913 code => 'for my $x (1..1) {}',
915 'loop::for::lex_range1' => {
916 desc => 'empty for loop with lexical var and 1 integer range',
918 code => 'for $x (1..1) {}',
920 'loop::for::pkg_range1' => {
921 desc => 'empty for loop with package var and 1 integer range',
923 code => 'for $x (1..1) {}',
925 'loop::for::defsv_range1' => {
926 desc => 'empty for loop with $_ and integer 1 range',
928 code => 'for (1..1) {}',
930 'loop::for::my_range4' => {
931 desc => 'empty for loop with my var and 4 integer range',
933 code => 'for my $x (1..4) {}',
935 'loop::for::lex_range4' => {
936 desc => 'empty for loop with lexical var and 4 integer range',
938 code => 'for $x (1..4) {}',
940 'loop::for::pkg_range4' => {
941 desc => 'empty for loop with package var and 4 integer range',
943 code => 'for $x (1..4) {}',
945 'loop::for::defsv_range4' => {
946 desc => 'empty for loop with $_ and integer 4 range',
948 code => 'for (1..4) {}',
951 'loop::for::my_list1' => {
952 desc => 'empty for loop with my var and 1 integer list',
954 code => 'for my $x (1) {}',
956 'loop::for::lex_list1' => {
957 desc => 'empty for loop with lexical var and 1 integer list',
959 code => 'for $x (1) {}',
961 'loop::for::pkg_list1' => {
962 desc => 'empty for loop with package var and 1 integer list',
964 code => 'for $x (1) {}',
966 'loop::for::defsv_list1' => {
967 desc => 'empty for loop with $_ and integer 1 list',
969 code => 'for (1) {}',
971 'loop::for::my_list4' => {
972 desc => 'empty for loop with my var and 4 integer list',
974 code => 'for my $x (1,2,3,4) {}',
976 'loop::for::lex_list4' => {
977 desc => 'empty for loop with lexical var and 4 integer list',
979 code => 'for $x (1,2,3,4) {}',
981 'loop::for::pkg_list4' => {
982 desc => 'empty for loop with package var and 4 integer list',
984 code => 'for $x (1,2,3,4) {}',
986 'loop::for::defsv_list4' => {
987 desc => 'empty for loop with $_ and integer 4 list',
989 code => 'for (1,2,3,4) {}',
992 'loop::for::my_array1' => {
993 desc => 'empty for loop with my var and 1 integer array',
994 setup => 'my @a = (1);',
995 code => 'for my $x (@a) {}',
997 'loop::for::lex_array1' => {
998 desc => 'empty for loop with lexical var and 1 integer array',
999 setup => 'my $x; my @a = (1);',
1000 code => 'for $x (@a) {}',
1002 'loop::for::pkg_array1' => {
1003 desc => 'empty for loop with package var and 1 integer array',
1004 setup => '$x = 1; my @a = (1);',
1005 code => 'for $x (@a) {}',
1007 'loop::for::defsv_array1' => {
1008 desc => 'empty for loop with $_ and integer 1 array',
1009 setup => 'my @a = (@a);',
1010 code => 'for (1) {}',
1012 'loop::for::my_array4' => {
1013 desc => 'empty for loop with my var and 4 integer array',
1014 setup => 'my @a = (1..4);',
1015 code => 'for my $x (@a) {}',
1017 'loop::for::lex_array4' => {
1018 desc => 'empty for loop with lexical var and 4 integer array',
1019 setup => 'my $x; my @a = (1..4);',
1020 code => 'for $x (@a) {}',
1022 'loop::for::pkg_array4' => {
1023 desc => 'empty for loop with package var and 4 integer array',
1024 setup => '$x = 1; my @a = (1..4);',
1025 code => 'for $x (@a) {}',
1027 'loop::for::defsv_array4' => {
1028 desc => 'empty for loop with $_ and integer 4 array',
1029 setup => 'my @a = (1..4);',
1030 code => 'for (@a) {}',
1033 'loop::while::i1' => {
1034 desc => 'empty while loop 1 iteration',
1035 setup => 'my $i = 0;',
1036 code => 'while (++$i % 2) {}',
1038 'loop::while::i4' => {
1039 desc => 'empty while loop 4 iterations',
1040 setup => 'my $i = 0;',
1041 code => 'while (++$i % 4) {}',