使用散列和散列引用的Perl速度比较
我很想比较是否更好地使用哈希或引用哈希,哈希引用,因为我理解只是一个指向哈希本身的指针,所以我认为应该没有速度差异.
我做了一个基本的基准测试,我发现哈希引用比使用哈希直接平均速度慢20-27%. 这是我使用的基本基准代码: use Benchmark qw(:all); cmpthese(10_000_000,{ hash => sub { my %hash = (); },hashref => sub { my $hahref = {}; } }); cmpthese(10_000_000,{ hash => sub { my %hash; $hash{fname}="first name"; $hash{mname}="middle name"; $hash{lname}="last name"; },hashref => sub { my $hahref; $hahref->{fname}="first name"; $hahref->{mname}="middle name"; $hahref->{lname}="last name"; },hashrefs => sub { my $hahref; $$hahref{fname}="first name"; $$hahref{mname}="middle name"; $$hahref{lname}="last name"; },}); 这是笔记本电脑戴尔,Windows 8,核心i7,16MB RAM的基准测试结果: Rate hashref hash hashref 5045409/s -- -17% hash 6045949/s 20% -- Rate hashrefs hashref hash hashrefs 615764/s -- -2% -21% hashref 625978/s 2% -- -19% hash 775134/s 26% 24% -- Output completed (1 min 6 sec consumed) 我的问题是,如果我的基准测试是正确的并且散列引用速度太慢,为什么像DBI这样的大多数模块都使用散列引用来返回结果.此外,大多数模块接受散列引用而不是参数的散列,并且还返回散列引用而不是散列. 解决方法
哈希更快地访问元素; hashrefs作为参数传递给函数的速度更快,或者作为函数的结果返回.如果你仔细想想,这是有道理的:
> hashref基本上是指向散列的指针,因此当Perl看到$href-> {xyz}时,它需要跟随指针找到散列,然后在散列中找到元素xyz.当Perl看到$hash {xyz}时,它不需要执行该初始指针跟随位;它可以直接找到元素xyz. 这主要是微优化,您应该选择哪种数据结构对您的程序最有意义.然而,对于那些你真的需要尽可能地提高速度的场合,它可以拥有两全其美…… 假设您有一个需要接受哈希值的函数(或者可能是hashref;您还没有决定)并且需要添加一些键.以下是您最初的两个选项: sub add_hash { my %hash = @_; return $hash{foo} + $hash{bar} + $hash{baz}; } sub add_hashref { my ($href) = @_; # faster than add_hash return $href->{foo} + $href->{bar} + $href->{baz}; # slower than add_hash } 现在让我们拉出Data::Alias.这是一个模块,它允许我们创建一个词法变量,作为另一个的别名.特别是,我们可以创建一个词法哈希变量,它的作用类似于hashref指向的哈希的别名. use Data::Alias; sub add_hashref_2 { my ($href) = @_; # faster than add_hash alias my %hash = %$href; # ... magic happens ... return $hash{foo} + $hash{bar} + $hash{baz}; # faster than add_hashref } 或者更好的是: use Data::Alias; sub add_hashref_3 { alias my %hash = %{ $_[0] }; return $hash{foo} + $hash{bar} + $hash{baz}; } …这避免了初始列表分配. 我强调这是微观优化.通常有更好的方法来加速你的代码 – 记忆,激进的算法更改,在XS中重写选定的热代码路径等等.但是有一些(非常有限的)场合,这种魔法可以帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |