gpt4 book ai didi

perl - 在 Moose 中,通过对象的内部哈希直接访问成员变量是否安全?

转载 作者:行者123 更新时间:2023-12-04 22:07:00 25 4
gpt4 key购买 nike

Moose 对象似乎是带有成员变量作为条目的祝福 hashrefs。使用哈希语法访问成员是否安全?我想要的只是获取/设置成员变量的简单能力,但我发现 perl 生成的访问器的速度对于我的应用程序来说是 Not Acceptable ,以至于我考虑在非 moose OO 中重写它。是的,我知道优化是一种可处以死刑的罪行,但我有十亿多行文件,添加一个简单的行计数器变量会增加十亿多函数调用,这会在单次运行中增加数小时。

显示缓慢的示例 (100x):

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 main;
use strict;
use warnings;
use Benchmark qw/timethese cmpthese/;

my $bull = Bullwinkle->new();
my $hash = { x => 0 };

cmpthese(-1,{
bull => sub{
$bull->x(1 + $bull->x());
},
bull_direct => sub{
++$bull->{x}
},
bull_counter => sub{
$bull->inc_counter();
},
hash => sub{
++$hash->{x}
},
});


利率公牛 Bull_counter 哈希公牛_direct
公牛 983040/s -- -28% -91% -92%
Bull_counter 1362629/s 39% -- -88% -88%
哈希 11251965/s 1045% 726% -- -3%
Bull_direct 11650844/s 1085% 755% 4% --

最佳答案

我会说打破封装永远是不安全的,Moose 与否。

请注意,您的 bull 测试不会慢 100 倍。请记住,它使用了两次访问器。就在信封的背面,它从每秒 1,000,000 次运行到每秒 2,000,000 次访问。与散列相比,它大约是 6 倍。但是,加上一堆这些减速,它可以加起来。

但是,我不认为 Moose 是那里的问题。当我用一个做同样事情的非 Moose 类尝试它时,结果并没有好多少。看起来大部分减速只是来自正常的面向对象的方法调用。使用 inc_counter 的非 Moose 类和 Moose 类之间的差异约为 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'} },
});

关于perl - 在 Moose 中,通过对象的内部哈希直接访问成员变量是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10102856/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com