让我们暂时忽略Damian Conway对任何给定子程序不超过三个位置参数的最佳实践.
以下两个示例在性能或功能方面有什么区别吗?
使用shift
:
sub do_something_fantastical { my $foo = shift; my $bar = shift; my $baz = shift; my $qux = shift; my $quux = shift; my $corge = shift; }
使用@_
:
sub do_something_fantastical { my ($foo, $bar, $baz, $qux, $quux, $corge) = @_; }
如果两个示例在性能和功能方面相同,那么人们对一种格式的看法是什么?显然,使用的示例@_
是更少的代码行,但使用它是否更清晰,shift
如另一个示例所示?欢迎有良好推理的意见.
有功能差异.该移修改@_
,并从分配@_
没有.如果您@_
之后不需要使用,那么这种差异可能对您无关紧要.我尝试总是使用列表分配,但我有时会使用shift
.
但是,如果我开始shift
,像这样:
my( $param ) = shift;
我经常创建这个bug:
my( $param, $other_param ) = shift;
那是因为我不shift
经常使用它,所以我忘了转到任务的右侧来改变它@_
.这是不使用的最佳实践shift
.我可以shift
像你在你的例子中那样为每个单独的行创建,但这只是单调乏味.
至少在我的系统上,它似乎依赖于Perl和架构的版本:
#!/usr/bin/perl -w use strict; use warnings; use autodie; use Benchmark qw( cmpthese ); print "Using Perl $] under $^O\n\n"; cmpthese( -1, { shifted => 'call( \&shifted )', list_copy => 'call( \&list_copy )', } ); sub call { $_[0]->(1..6); # Call our sub with six dummy args. } sub shifted { my $foo = shift; my $bar = shift; my $baz = shift; my $qux = shift; my $quux = shift; my $corge = shift; return; } sub list_copy { my ($foo, $bar, $baz, $qux, $quux, $corge) = @_; return; }
结果:
Using Perl 5.008008 under cygwin Rate shifted list_copy shifted 492062/s -- -10% list_copy 547589/s 11% -- Using Perl 5.010000 under MSWin32 Rate list_copy shifted list_copy 416767/s -- -5% shifted 436906/s 5% -- Using Perl 5.008008 under MSWin32 Rate shifted list_copy shifted 456435/s -- -19% list_copy 563106/s 23% -- Using Perl 5.008008 under linux Rate shifted list_copy shifted 330830/s -- -17% list_copy 398222/s 20% --
因此看起来list_copy通常比移位快20%,除了在Perl 5.10之外,其中移位实际上稍快一些!
请注意,这些是快速得出的结果.实际速度差异将大于此处列出的速度差异,因为Benchmark还会计算调用和返回子程序所需的时间,这将对结果产生调节作用.我没有做过任何调查,看看Perl是否正在进行任何特殊的优化.你的旅费可能会改变.
保罗
我认为移位示例比使用@_慢,因为它是6个函数调用而不是1.它是否明显甚至可测量是一个不同的问题.将每个抛出10k迭代循环并计时.
至于美学,我更喜欢@_方法.使用带有意外剪切和粘贴的移位方法似乎太容易弄乱变量的顺序.另外,我见过很多人这样做:
sub do_something { my $foo = shift; $foo .= ".1"; my $baz = shift; $baz .= ".bak"; my $bar = shift; $bar .= ".a"; }
恕我直言,这是非常讨厌的,很容易导致错误,例如,如果你切割baz块并将其粘贴在条形块下面.我所有人都在将变量定义在它们所使用的位置附近,但我认为在函数顶部定义传入的变量优先.