首先,您想使用-1
而不是0
forsplit
的第三个参数,因此您不会删除任何存在但为空的字段。
my @field_names = qw(foo bar xyzzy);
my $record = "33\t45\t78\n";
my %feqv_hash;
@feqv_hash{@field_names} = split /\t/, $record, -1;
让我们看看检查有多慢。
use strict;
use warnings;
use Benchmark qw( timethese );
use Carp qw( croak );
my %tests = (
without => <<'__EOI__',
my %feqv_hash;
@feqv_hash{@field_names} = split /\t/, $record, -1;
__EOI__
with => <<'__EOI__',
my @field_values = split /\t/, $record, -1;
croak if @field_names != @field_values;
my %feqv_hash;
@feqv_hash{@field_names} = @field_values;
__EOI__
);
$_ = 'use strict; use warnings; our @field_names; our $record; '.$_
for values %tests;
{
local our @field_names = qw(foo bar xyzzy);
local our $record = "33\t45\t78\n";
timethese(-3, \%tests);
}
结果:
without check: 2.7 microseconds
with check: 4.1 microseconds
----------------
check: 1.4 microseconds
检查需要 1.4 微秒。我不知道你为什么认为有问题。
但是通过使用 扫描字符串,可以将时间缩短近一半tr/\t//
。[更新:或者通过在标量上下文中使用列表赋值]
use strict;
use warnings;
use Benchmark qw( cmpthese );
use Carp qw( croak );
my %tests = (
temp_array => <<'__EOI__',
my @field_values = split /\t/, $record, -1;
croak if @field_names != @field_values;
my %feqv_hash;
@feqv_hash{@field_names} = @field_values;
__EOI__
tr => <<'__EOI__',
croak if @field_names != 1 + $record =~ tr/\t//;
my %feqv_hash;
@feqv_hash{@field_names} = split /\t/, $record, -1;
__EOI__
aassign => <<'__EOI__',
my %feqv_hash;
( @feqv_hash{@field_names} = split /\t/, $record, -1 ) == @field_names
or croak;
__EOI__
);
$_ = 'use strict; use warnings; our @field_names; our $record; '.$_
for values %tests;
{
local our @field_names = qw(foo bar xyzzy);
local our $record = "33\t45\t78\n";
cmpthese(-3, \%tests);
}
结果:
Rate temp_array tr aassign
temp_array 233472/s -- -30% -36%
tr 334671/s 43% -- -8%
aassign 362326/s 55% 8% --