在Perl中,生成getter和setter而不是硬编码是有缺点的吗?

前端之家收集整理的这篇文章主要介绍了在Perl中,生成getter和setter而不是硬编码是有缺点的吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在下面的示例模块中,通过将匿名子例程添加到符号表来生成getter和setter.在以这种方式创建方法之后,生成代码功能上是否等同于(在行为,速度等方面)具有手动编写的getter和setter的模块,或者这种方法是否具有某种固有的责任? (我已经做了一些基本的速度基准测试,到目前为止还没有发现任何差异.)
package Module;    
use strict;
use warnings;

BEGIN {
    my @attr = qw(author title number);
    no strict 'refs';
    for my $a (@attr){
        *{__PACKAGE__ . "::get_$a"} = sub { $_[0]->{$a}         };
        *{__PACKAGE__ . "::set_$a"} = sub { $_[0]->{$a} = $_[1] };
    }
}

sub new {
    my $class = shift;
    bless { @_ },$class;
}

1;

解决方法

如果在两种情况下生成代码都相同,则运行时性能应该没有差异.但是,这通常是不可能的,除非您使用字符串eval来创建子例程.例如,您提供的代码
... = sub { $_[0]->{$a} };

将比您手动编写的代码慢得多:

sub foo { $_[0]->{'foo'} }

只是因为前者必须在将变量$a作为哈希的键之前获取变量$a的值,而后者使用常量作为其哈希键.另外,顺便说一下,换班通常比$_ [0]快.这是一些基准代码

use Benchmark qw(cmpthese);

package Foo;

sub manual_shift { shift->{'foo'} }
sub manual_index { $_[0]->{'foo'} }

my $attr = 'foo';

*dynamic_shift = sub { shift->{$attr} };
*dynamic_index = sub { $_[0]->{$attr} };

package main;

my $o = bless { foo => 123 },'Foo';

cmpthese(-2,{
  manual_shift  => sub { my $a = $o->manual_shift },manual_index  => sub { my $a = $o->manual_index },dynamic_shift => sub { my $a = $o->dynamic_shift },dynamic_index => sub { my $a = $o->dynamic_index },});

和我的系统上的结果:

Rate dynamic_index  manual_index dynamic_shift  manual_shift
dynamic_index 1799024/s            --           -3%           -4%           -7%
manual_index  1853616/s            3%            --           -1%           -4%
dynamic_shift 1873183/s            4%            1%            --           -3%
manual_shift  1937019/s            8%            4%            3%            --

它们非常接近以至于差异可能会在噪音中消失,但在许多试验中我认为你会发现“手动换档”变体是最快的.但是像所有这样的微基准测试一样,你必须在你的硬件和你的perl版本上测试你的确切场景以确保任何事情.

这里的字符串eval被投入到混合中.

eval "sub eval_index { \$_[0]->{'$attr'} }";
eval "sub eval_shift { shift->{'$attr'} }";

它应该与“手动”变体完全相同,加上或减去统计噪声.我的结果:

Rate dynamic_index manual_index dynamic_shift manual_shift eval_shift eval_index
dynamic_index 1820444/s            --          -1%           -2%          -3%        -4%        -5%
manual_index  1835005/s            1%           --           -1%          -2%        -3%        -4%
dynamic_shift 1858131/s            2%           1%            --          -1%        -2%        -3%
manual_shift  1876708/s            3%           2%            1%           --        -1%        -2%
eval_shift    1894132/s            4%           3%            2%           1%         --        -1%
eval_index    1914060/s            5%           4%            3%           2%         1%         --

同样,这些都非常接近,你必须付出巨大的努力,并进行许多试验来整理噪音信号.但是使用常量作为散列键和使用变量(必须首先检索其值)作为散列键之间的区别应该显示出来. (移位优化是一个单独的问题,更有可能在perl的过去或未来版本中以某种方式改变.)

原文链接:https://www.f2er.com/Perl/172148.html

猜你在找的Perl相关文章