首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获得同样快速的子参数?

如何获得同样快速的子参数?
EN

Stack Overflow用户
提问于 2013-07-09 23:32:30
回答 2查看 122关注 0票数 1

参数在@_中传递给perl子程序。为了使我的程序更容易阅读,我一直使用这种模式来获得命名的参数:

代码语言:javascript
复制
sub foo1 {
    my ($bar, $baz) = @_;
    do_something($bar,$baz);
}

但是它会导致$_[0]$_[1]被复制。如果我要直接访问$_[0],而不是在上面的模式中访问$bar,那么我可以按值调用/别名访问调用者参数,通常使用的是按引用调用的警告,但速度要快得多(参见下面的演示)。

让我怀疑的是,由于性能原因,my ($param1, $param2 ...) = @_;模式是不好的。所以我发现我必须在快速程序和可读程序之间做出选择,这是一个不可能的选择。

最后,我编写了一些子程序,其中性能是$_[<n>]的重点,而上面的模式则是其他方面的重点。问题是,我通常事先不知道瓶颈在哪里;-)

是否有一种方法可以获得同样快速的命名参数?或者在这件事上什么是经典的?$_[0]$bar

附录:速度演示

代码语言:javascript
复制
use Time::HiRes qw(time);

# Lets just do *something* with the parameters - here we just add up all
# their lengths
my $totalLength = 0;

sub foo1 {
    # Access $_[0] directly - effectively call-by-reference
    $totalLength += length($_[0]);
}

sub foo2 {
    # Access a copy of $_[0] - effectively call-by-value  - involves
    # copying
    my ($bar) = @_;
    $totalLength += length($bar);
}

my $a = 'b' x 10_000;
my $t0 = time;
foreach (0..1_000_000) {
    foo1($a);
}
printf "foo1 %2.6f\n", time - $t0;

$t0 = time;
foreach (0..1_000_000) {
    foo2($a);
}
printf "foo2 %2.6f\n", time - $t0;

印出

代码语言:javascript
复制
foo1 0.329470
foo2 1.280364

foo1比foo2快4倍,因为它避免了复制$_[0]

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-09 23:38:36

通过hashref传递它们:

代码语言:javascript
复制
my %args = (bar=>1, baz=>2);
mySub(\%args);
sub mySub {
    my $args = shift;
    doSomething($args); # pass entire parameter list for cheap!
    doSomething2($args{bar}); # Use specific parameter
}

坦率地说,我有点怀疑性能的好处(散列访问不是免费的),但是如果真的需要的话,可以对其进行基准测试。但这并不是最好的性能选项(见下文),甚至可能不需要(见最后一部分),而且我不认为有多少需要尝试的。

另一种选择(有点糟糕,但性能更好)是使用$_[1]等.但是通过广泛的评论来打击不可读性。

代码语言:javascript
复制
           # pass `baz`
doSomething($_[1]);

另一个性能更高但性能更差的设计选项是绕过所有传递的参数,并使用全局变量传递参数。

代码语言:javascript
复制
our $bar = 1;
mySub();
sub mySub {
    #do something with $bar. Pray some other code didn't clobber it
}

最后考虑:

如果您的代码是如此的调优,并且对性能非常敏感,以至于复制几个标量会产生很大的不同,那么您的可能希望退出Perl到纯C中,用于那些函数

但是,正如Knuth所说,请不要过早地优化

首先, 分析你的整个应用程序,并确保标量参数复制确实是您最大的瓶颈所在。我并不怀疑这是合理的,但通常情况下,瓶颈在其他地方(IO、DB、缓慢数据结构等)。

换句话说,如果$operation_X占运行时的0.01%,那么$operation_X的实现速度可以提高4倍,这一点也没有任何意义。加快它的4倍是根本不值得的麻烦,给予降低可读性。

票数 6
EN

Stack Overflow用户

发布于 2013-07-10 01:59:09

那么,如果您按照这个顺序将$bar和$baz传递给subdo_something(),另一个糟糕的选项是使用以下可怕的语法--但有文档记录--语法:

代码语言:javascript
复制
sub foo1 { goto &do_something}

...which将立即将上下文传递给do_something()。没有帮助文件的参数,但它可能是最快的传递到另一个例行机制的一堆。:-)

见鬼,我会亲自否决这个答案.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17560045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档