English 中文(简体)
高效阵列
原标题:perl efficient array concatenation to hash
use strict;
use Time::HiRes qw[gettimeofday tv_interval];

my $start_index = int(rand(50))+100;#this value is arbitrary for this discussion
my $duration = 75;#also arbitrary but assume it will always be several times the size of the dataset

my $hash = {};
my @dataset = qw(foo bar baz qux bob joe sue tom);
my $partial = $duration % scalar(@dataset);
my $full = ($duration - $partial) / scalar(@dataset);

my $start = [gettimeofday()];
for my $index (0..$#dataset) {
    my $w = $dataset[$index];
    for (0..$full-1) {
        my $i = $start_index + $index + (scalar(@dataset) * $_);
        $hash->{$i} = $w;
    }
}
print "  full ".tv_interval($start)." secs
";$start = [gettimeofday()];
for my $index (0..$partial-1) {
    my $w = $dataset[$index];
    my $s = $start_index + $index + (scalar(@dataset) * $full);
    $hash->{$s} = $w;
}
print "  part ".tv_interval($start)." secs
";$start = [gettimeofday()];

如果使用一个(,)较大的数据集和时间长度,则“完整”文件上的上述逻辑需要60至120秒才能执行。 是否有效率更高的方法实现同样的结果?

Edit:
To give more perspective as to the size of the dataset this is used in, this performance optimization is for a signal processing program.

最佳回答

解决办法:

use strict;
use warnings;
use Time::HiRes qw[gettimeofday tv_interval];

sub min ($$) {$_[$_[0] > $_[1]]}

my $start_index = int(rand(50))+100;#this value is arbitrary for this discussion
my $duration = 75;#also arbitrary but assume it will always be several times the size of the dataset

{
    my @dataset = qw(foo bar baz qux bob joe sue tom);
    my $hash = {};
    my $partial = $duration % scalar(@dataset);
    my $full = ($duration - $partial) / scalar(@dataset);

    my $start = [gettimeofday()];
    for my $index (0..$#dataset) {
        my $w = $dataset[$index];
        for (0..$full-1) {
            my $i = $start_index + $index + (scalar(@dataset) * $_);
            $hash->{$i} = $w;
        }
    }
    print "  full: ".tv_interval($start)." secs
";$start = [gettimeofday()];
    for my $index (0..$partial-1) {
        my $w = $dataset[$index];
        my $s = $start_index + $index + (scalar(@dataset) * $full);
        $hash->{$s} = $w;
    }
    print "  part: ".tv_interval($start)." secs
";$start = [gettimeofday()];

    #print "$_ => $hash->{$_}
" foreach (sort {$a <=> $b} keys %$hash);
}

#############
print "

";
#############

{
    my $dataset = [qw(foo bar baz qux bob joe sue tom)];
    my $hash;
    $hash //= {};

    my $remaining = $duration;
    my $phase = 0;#arbitrary
    my $start = [gettimeofday()];
    while (1) {
        last unless $remaining;
        my $chunk_size = min($remaining, scalar(@$dataset) - $phase);
        #print "$chunk_size   ".($start_index+$duration-$remaining)."..".($start_index+$duration-$remaining+$chunk_size-1)."   $phase..".($phase+$chunk_size-1)."
";
        @{$hash}{($start_index + $duration - $remaining .. $start_index + $duration - $remaining + $chunk_size - 1)} = @{$dataset}[$phase .. $phase + $chunk_size - 1];
        $remaining -= $chunk_size;
        $phase = ($phase + $chunk_size) % scalar(@$dataset);
    }
    print "  time: ".tv_interval($start)." secs
";$start = [gettimeofday()];

    #print "$_ => $hash->{$_}
" foreach (sort {$a <=> $b} keys %$hash);
}
问题回答

象你所能做的唯一优化一样,在休息室外计算 s(@dataset):

my $data_set_size = scalar(@dataset);

lo

my $i = floor($start_index + $index + ($data_set_size * $_));




相关问题
Why does my chdir to a filehandle not work in Perl?

When I try a "chdir" with a filehandle as argument, "chdir" returns 0 and a pwd returns still the same directory. Should that be so? I tried this, because in the documentation to chdir I found: "...

How do I use GetOptions to get the default argument?

I ve read the doc for GetOptions but I can t seem to find what I need... (maybe I am blind) What I want to do is to parse command line like this myperlscript.pl -mode [sth] [inputfile] I can use ...

Object-Oriented Perl constructor syntax and named parameters

I m a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot. package Foo; #In Perl, the constructor is just a subroutine called new. sub new { #I ...

Where can I find object-oriented Perl tutorials? [closed]

A Google search yields a number of results - but which ones are the best? The Perl site appears to contain two - perlboot and perltoot. I m reading these now, but what else is out there? Note: I ve ...

热门标签