我会说打破封装永远不安全,Moose 与否。
请注意,您的bull
测试不会慢 100 倍。请记住,它使用了两次访问器。就在信封的背面,它从每秒 1,000,000 次运行到每秒 2,000,000 次访问。与散列相比,它大约是 6 倍。不过,加上一堆减速,它可以加起来。
但是,我不认为 Moose 是那里的问题。当我尝试使用做同样事情的非 Moose 类时,结果并没有那么好。看起来大部分减速只是来自普通的面向对象的方法调用。使用的非 Moose 和 Moose 类之间的差异inc_counter
大约是 2 倍。
基准是非常棘手的事情。您确实需要努力梳理出不同的部分,并确保您测试适当的基本案例。当你得到疯狂的数字时,你应该从怀疑者开始并调整事情,直到它们不再那么疯狂。例如,即使 Moose 很慢,如果它像您推测的那样慢,我认为没有人会使用它。慢一点是一回事,数量级或数量级是另一回事。
我也对基准感到好奇,我想用make_immutable
. 这是我在运行 Lion 的 Mac Pro 上使用 Moose-2.0403 的默认 Perl5.14.2 的结果。Bull 是您的原始代码,Rocky 使用make_immutable
,而 Natasha 是一个非 Moose 类,它做同样的事情:
Rate bull rocky natasha bull_counter rocky_counter natasha_x rocky_x bull_x natasha_counter rocky_direct bull_direct natasha_direct hash
bull 728177/s -- -6% -17% -42% -43% -65% -66% -67% -71% -93% -94% -94% -95%
rocky 771011/s 6% -- -12% -39% -39% -63% -64% -65% -70% -93% -93% -94% -95%
natasha 877713/s 21% 14% -- -30% -31% -58% -59% -60% -66% -92% -92% -93% -94%
bull_counter 1260308/s 73% 63% 44% -- -1% -40% -42% -42% -51% -88% -89% -89% -91%
rocky_counter 1274310/s 75% 65% 45% 1% -- -39% -41% -42% -50% -88% -89% -89% -91%
natasha_x 2105717/s 189% 173% 140% 67% 65% -- -3% -4% -17% -81% -81% -82% -85%
rocky_x 2163925/s 197% 181% 147% 72% 70% 3% -- -1% -15% -80% -81% -82% -85%
bull_x 2184533/s 200% 183% 149% 73% 71% 4% 1% -- -14% -80% -80% -82% -85%
natasha_counter 2548621/s 250% 231% 190% 102% 100% 21% 18% 17% -- -77% -77% -79% -82%
rocky_direct 10901037/s 1397% 1314% 1142% 765% 755% 418% 404% 399% 328% -- -3% -9% -24%
bull_direct 11202734/s 1438% 1353% 1176% 789% 779% 432% 418% 413% 340% 3% -- -6% -21%
natasha_direct 11939231/s 1540% 1449% 1260% 847% 837% 467% 452% 447% 368% 10% 7% -- -16%
hash 14252488/s 1857% 1749% 1524% 1031% 1018% 577% 559% 552% 459% 31% 27% 19% --
这是我的程序:
#!/Users/brian/bin/perls/perl5.14.2
use v5.10.1;
use strict;
use warnings;
use Benchmark qw/timethese cmpthese/;
package Bullwinkle {
use strict;
use warnings;
use Moose;
has 'x' => (is => 'rw', default => 0);
# counter is also slow
has 'counter' => (
traits => ['Counter'],
is => 'ro',
isa => 'Num',
default => 0,
handles => {
inc_counter => 'inc',
},
);
}
package Rocky {
use strict;
use warnings;
use Moose;
has 'x' => (is => 'rw', default => 0);
# counter is also slow
has 'counter' => (
traits => ['Counter'],
is => 'ro',
isa => 'Num',
default => 0,
handles => {
inc_counter => 'inc',
},
);
__PACKAGE__->meta->make_immutable;
}
package Natasha {
use strict;
use warnings;
sub new { bless { 'x' => 0 }, $_[0] }
sub inc_counter { $_[0]->{x} += 1 }
sub x {
if( defined $_[1] ) { $_[0]->{x} = $_[1] }
else { $_[0]->{x} }
}
}
my $bull = Bullwinkle->new;
my $rocky = Rocky->new;
my $natasha = Natasha->new;
my $hash = { 'x' => 0 };
cmpthese(-1,{
bull => sub { $bull->x(1 + $bull->x ) },
bull_x => sub { $bull->x },
bull_direct => sub { ++$bull->{'x'} },
bull_counter => sub { $bull->inc_counter },
rocky => sub { $rocky->x(1 + $rocky->x ) },
rocky_x => sub { $rocky->x },
rocky_direct => sub { ++$rocky->{'x'} },
rocky_counter => sub { $rocky->inc_counter },
natasha => sub { $natasha->x(1 + $natasha->x ) },
natasha_x => sub { $natasha->x },
natasha_direct => sub { ++$natasha->{'x'} },
natasha_counter => sub { $natasha->inc_counter },
hash => sub { ++$hash->{'x'} },
});