Dos micro optimizaciones: correlaciona el hash interno en lugar de la desreferenciación constante y el búfer de impresión constante. Es posible deshacerse de la clasificación utilizando formatos de almacenamiento alternativos, probando dos variantes. Resultados:
Rate original try3 alternative alternative2
original 46.1/s -- -12% -21% -32%
try3 52.6/s 14% -- -10% -22%
alternative 58.6/s 27% 11% -- -13%
alternative2 67.5/s 46% 28% 15% --
Conclusión:
Es mejor utilizar el formato de almacenamiento preclasificado, pero sin C victoria sería probablemente menos de 100% (en mi conjunto de datos de prueba). La información proporcionada acerca de los datos sugiere que las claves en hash externo son números casi secuenciales, por lo que esta demanda de matriz.
Guión:
#!/usr/bin/env perl
use strict; use warnings;
use Benchmark qw/timethese cmpthese/;
my %signal_db = map { $_ => {} } 1..1000;
%$_ = map { $_ => $_ } 'a'..'z' foreach values %signal_db;
my @signal_db = map { { cycle => $_ } } 1..1000;
$_->{'samples'} = { map { $_ => $_ } 'a'..'z' } foreach @signal_db;
my @signal_db1 = map { $_ => [] } 1..1000;
@$_ = map { $_ => $_ } 'a'..'z' foreach grep ref $_, @signal_db1;
use Sort::Key qw(nsort);
sub numerically { $a <=> $b }
my $result = cmpthese(-2, {
'original' => sub {
open my $out, '>', 'tmp.out';
foreach my $cycle (sort numerically keys %signal_db) {
foreach my $key (sort keys %{$signal_db{$cycle}}) {
print $out $signal_db{$cycle}{$key}.$key."\n";
}
}
},
'try3' => sub {
open my $out, '>', 'tmp.out';
foreach my $cycle (map $signal_db{$_}, sort numerically keys %signal_db) {
my $tmp = '';
foreach my $key (sort keys %$cycle) {
$tmp .= $cycle->{$key}.$key."\n";
}
print $out $tmp;
}
},
'alternative' => sub {
open my $out, '>', 'tmp.out';
foreach my $cycle (map $_->{'samples'}, @signal_db) {
my $tmp = '';
foreach my $key (sort keys %$cycle) {
$tmp .= $cycle->{$key}.$key."\n";
}
print $out $tmp;
}
},
'alternative2' => sub {
open my $out, '>', 'tmp.out';
foreach my $cycle (grep ref $_, @signal_db1) {
my $tmp = '';
foreach (my $i = 0; $i < @$cycle; $i+=2) {
$tmp .= $cycle->[$i+1].$cycle->[$i]."\n";
}
print $out $tmp;
}
},
});
¡Gracias por 3 respuestas muy útiles y detalladas! Desearía poder aceptarlos a todos :) –