package SlotP1;
use strict;
use warnings;
use Types::Standard 'Int';
use slot x => Int, rw => 1, def => 0;
use slot y => Int, rw => 1, def => 0;
1;

package SlotP2;
use strict;
use warnings;
use Types::Standard 'Int';
use parent -norequire, 'SlotP1';
use slot z => rw => 1, def => 0;
1;

package MooP1;
use strict;
use warnings;
use Moo;
use Types::Standard 'Int';
has x => (is => 'rw', isa => Int, default => 0);
has y => (is => 'rw', isa => Int, default => 0);
1;

package MooP2;
use strict;
use warnings;
use Moo;
use Types::Standard 'Int';
extends 'MooP1';
has z => (is => 'rw', default => 0);
1;

package MooseP1;
use strict;
use warnings;
use Moose;
has x => (is => 'rw', isa => 'Int', default => 0);
has y => (is => 'rw', isa => 'Int', default => 0);
__PACKAGE__->meta->make_immutable;
1;

package MooseP2;
use strict;
use warnings;
use Moose;
extends 'MooseP1';
has z => (is => 'rw', default => 0);
__PACKAGE__->meta->make_immutable;
1;

package main;
use Benchmark 'cmpthese';

my $slot  = SlotP2->new(x => 10, y => 30, z => 10);
my $moo   = MooP2->new(x => 10, y => 30, z => 10);
my $moose = MooseP2->new(x => 10, y => 30, z => 10);

cmpthese 1_000_000, {
  'slot'  => sub { my $y = $slot->y(20);  my $z = $slot->z(30); },
  'moo'   => sub { my $y = $moo->y(20);   my $z = $moo->z(30); },
  'moose' => sub { my $y = $moose->y(20); my $z = $moose->z(30); },
};
