Scalar::Util::Ref
instanceof演算子を実装してみた。
Scalar::Util::Ref
#!perl use strict; use IO::File; use instanceof; my $x = IO::File->new(); if($x << 'IO::Handle'){ print "$x is an instance of 'IO::Handle'\n"; } __END__
Scalar::Util::blessed()&isa()と比べると,Perl 5.8.5 on Linuxでこんな感じになる。
For Foo=HASH(0x8246528) Rate scalar_util instanceof scalar_util 55138/s -- -60% instanceof 137845/s 150% -- For Foo::X::X::X=HASH(0x835811c) Rate scalar_util instanceof scalar_util 45948/s -- -53% instanceof 98248/s 114% -- For Unrelated=HASH(0x835cf5c) Rate scalar_util instanceof scalar_util 49320/s -- -55% instanceof 109226/s 121% -- For undef Rate scalar_util instanceof scalar_util 122879/s -- -62% instanceof 319956/s 160% --
このようにほぼ常に2倍ほど速いので,isa()を大量に呼び出す場合は有効かもしれない。更に,5.8.xでは5.10.0の機能を効率の悪いやり方でエミュレートしているので,最新のPerlではもう少し高速になるはず。
ベンチマークコード:
#!perl -w use strict; use Benchmark qw(:all); use Scalar::Util qw(blessed); BEGIN{ package Base; sub new{ bless {} => shift; } package Foo; our @ISA = qw(Base); package Foo::X; our @ISA = qw(Foo); package Foo::X::X; our @ISA = qw(Foo::X); package Foo::X::X::X; our @ISA = qw(Foo::X::X); package Unrelated; our @ISA = qw(Base); } foreach my $x (Foo->new, Foo::X::X::X->new, Unrelated->new, undef){ print 'For '; if(defined $x){ print $x; } else{ print 'undef'; } print "\n"; my $i = 0; cmpthese -1 => { 'scalar_util' => sub{ for(1 .. 10){ $i++ if blessed($x) && $x->isa('Foo'); } }, 'instanceof' => sub{ use instanceof; for(1 .. 10){ $i++ if $x << 'Foo'; } }, }; print "\n"; } __END__