我遇到了代码:
sub insertDecimal
{
my $number = shift;
my $sigDigRight = shift;
if ($number =~ /\./) { return ($number); }
elsif (length $number < $sigDigRight) { return ($number); }
else
{
my $leftSide = substr($number, 0, (length $number)-$sigDigRight);
my $rightSide = substr($number, (length $number)-$sigDigRight, );
return ($leftSide . "." . $rightSide);
}
}
我希望改进/重写为:
sub insertDecimal
{
my ($number, $sigDigRight) = @_;
return $number if index ($number, '.') != -1 or length $number < $sigDigRight;
# YES! substr takes an LVALUE ... perldoc it for more :)
substr($number, -$sigDigRight, 0) = '.';
return $number;
}
我很惊讶一些74毫米的记录在第二版中几乎没有任何改进。
问题:
答案 0 :(得分:2)
这两个例程看起来基本上都做了相同的工作:
扫描$number
个字符(任何编译器都应该能够将该正则表达式匹配减少到index
)
将$number
的长度与限制
可能会在$number
使用左值substr
(或者,只是利用substr
的第四个参数)可以使插入更有效率,但毕竟,事情必须被移动。
在我看来,优化的最大机会来自于检查小数点之前移动长度检查。
我很想重新编写你的例行程序
sub insertDecimal {
my ($number, $sigDigRight) = @_;
return $number if length($number) < $sigDigRight;
return $number if index($number, '.') >= 0;
substr($number, -$sigDigRight, 0, '.');
$number;
}
我发现简单的决定和简短的线条更容易理解。我认为这不应该改变函数的正确性。
一个丑陋的选择是:
sub gah {
my ($number, $sigDigRight) = @_;
my $n = length($number) - $sigDigRight;
return $number unless $n > 0;
$number =~ s{\A ([^.]{$n}) ([^.]+) \z}{$1.$2}x;
$number;
}
将.
的检查与替换操作结合起来。
同样,我无法确定这是否符合您的规范,但这是您需要探索的内容。
我可能不会选择gah
,除非改善超过至少花费一个小时左右的时间的20%。在我的系统上,它将一个简单的例子减慢了1000%。