#!/usr/bin/perl
use Benchmark;
use lib './blib/lib', '../blib/lib';
use strict qw(vars subs);
use Object::Hybrid qw(promote);
my $plain = {a => 1};
my $blessed = bless {a => 1}, 'Foo';
my $hybrid = Object::Hybrid->new({a => 1});
my $hybrid_tieable = Object::Hybrid->new({a => 1}, tieable => 1);
my $hybrid_tieable = Object::Hybrid->new({a => 1}, tieable => 1);
my $hybrid_tieable_mutable = Object::Hybrid->new({a => 1}, tieable => 1, mutable => 1);
my $hybrid_tieable_caller = Object::Hybrid->new({a => 1}, tieable => 1, caller => 1);
use Tie::Hash;
my ($tied, $hybrid_tied, $hybrid_tied_mutable, $hybrid_tied_caller);
foreach ($tied, $hybrid_tied, $hybrid_tied_mutable, $hybrid_tied_caller) {
tie %$_, 'Tie::StdHash';
$_->{a} = 1;
}
promote($hybrid_tied);
promote($hybrid_tied_mutable, mutable => 1);
promote($hybrid_tied_caller, caller => 1);
{
package Foo;
use overload '*{}' => sub{}; # this makes very tiny slowdown of blessed
}
my $hybrid_class = ref promote({});
my $iterations = 100000;
timethese( $iterations, {
new => sub{ Object::Hybrid->new({}) }, # includes DESTROY() costs
new2class => sub{ Object::Hybrid->new({} => 'Foo') }, # includes DESTROY() costs
promote => sub{ promote({}) }, # includes DESTROY() costs
promote2class => sub{ promote({} => 'Bar' ) }, # includes DESTROY() costs
promote_bless => sub{ bless {}, $hybrid_class; }, # includes DESTROY() costs
promote_bless_nodestroy => sub{ bless {}, 'NO_DESTROY'; }, # no DESTROY() costs
hybrid => sub{ $hybrid->{a} },
hybrid_method => sub{ $hybrid->FETCH('a') },
hybrid_method_fast => sub{ $hybrid->fast->FETCH('a') },
hybrid_can => sub{ $hybrid->can('FETCH') },
hybrid_can_switch => sub{ (tied(%$hybrid)||$hybrid)->can('FETCH') },
hybrid_can_fast => sub{ $hybrid->fast->can('FETCH') },
hybrid_tieable_method => sub{ $hybrid_tieable->FETCH('a') },
hybrid_tieable_method_fast => sub{ $hybrid_tieable->fast->FETCH('a') },
hybrid_tieable_mutable_method => sub{ $hybrid_tieable_mutable->FETCH('a') },
hybrid_tieable_mutable_method_fast => sub{ $hybrid_tieable_mutable->fast->FETCH('a') },
hybrid_tieable_caller_method => sub{ $hybrid_tieable_caller->FETCH('a') },
hybrid_tieable_caller_method_fast => sub{ $hybrid_tieable_caller->fast->FETCH('a') },
hybrid_tied => sub{ $hybrid_tied->{a} },
hybrid_tied_method => sub{ $hybrid_tied->FETCH('a') },
hybrid_tied_method_fast => sub{ $hybrid_tied->fast->FETCH('a') },
hybrid_tied_can => sub{ $hybrid_tied->can('FETCH') },
hybrid_tied_can_switch => sub{ (tied(%$hybrid_tied)||$hybrid_tied)->can('FETCH') },
hybrid_tied_can_fast => sub{ $hybrid_tied->fast->can('FETCH') },
hybrid_tied_mutable_method => sub{ $hybrid_tied_mutable->FETCH('a') },
hybrid_tied_mutable_method_fast => sub{ $hybrid_tied_mutable->fast->FETCH('a') },
hybrid_tied_caller_method => sub{ $hybrid_tied_caller->FETCH('a') },
hybrid_tied_caller_method_fast => sub{ $hybrid_tied->fast->FETCH('a') },
primitive => sub{ $plain->{a} },
primitive_blessed => sub{ $blessed->{a} },
primitive_tied => sub{ $tied->{a} },
primitive_switch => sub{ tied(%$plain) ? tied(%$plain)->FETCH('a') : $plain->{a} },
primitive_tied_switch => sub{ tied(%$tied) ? tied(%$tied )->FETCH('a') : $tied->{a} },
primitive_tied_method => sub{ tied(%$tied )->FETCH('a') },
});