My goal is to optimize both. Since I'm new to this aspect of perl I simply suggested it would be more beneficial to start with the simpler optimization, than go the more complex one. I guess our approaches are different. I am a student and currently my ultimate goal here is to learn. I think this is achieved better going from simpler things to more complex ones. According to your approach, if I were given a black box that solves my problem in a split of a second, I should have used it and be over with it. This will solve the problem obviously, but will teach me nothing. Anyway, I'm sorry to hear that you think I'm "bordering on irrational obsession". This was actually quite offending.
UPDATE: re. your update, I did. Quite surprisingly, it now takes significantly longer to run. I guess I have some error, but I can't see it. Inline version:
use strict;
use warnings;
use List::Util qw(max min);
use Time::HiRes qw(time);
# this builds a structure that is usually retrieved from disk.
# in this example we will use this structure again and again,
# but in the real program we obviously retrieve a fresh structure
# at each iteration
my $simulation_h = {};
for ( 1 .. 70000 ) {
my $random_start = int( rand(5235641) );
my $random_length = int( rand(40000) );
push @{ $simulation_h->{$random_start} }, $random_length;
}
my $zone_o = {
_chromosome_length => 5235641,
_legal_range => [ { FROM => 100000, TO => 200000 } ]
};
my $start_time = time;
scenario();
print "total loop time: " . ( time - $start_time ) . " seconds\n";
my $temp_gene_to_legal_range;
my $gene_to;
sub scenario {
for ( my $i = 0 ; $i < 50 ; $i++ ) {
print "i=$i time=" . ( time - $start_time ) . " seconds\n";
# originally there was a retreive of $simulation_h from disk h
+ere
# iterate genes
foreach my $gene_from ( keys %{$simulation_h} ) {
foreach my $gene_length ( @{ $simulation_h->{$gene_from} }
+ ) {
### inlining gene_to_legal_range
$gene_to =
( ( $gene_from + $gene_length - 1 )
% ( $zone_o->{_chromosome_length} ) ) + 1;
if ( $gene_to < $gene_from ) {
# split
# low range first
$temp_gene_to_legal_range = [
{ FROM => 0, TO => $gene_to },
{
FROM => $gene_from,
TO => $zone_o->{_chromosome_length}
}
];
}
else {
# single
$temp_gene_to_legal_range =
[ { FROM => $gene_from, TO => $gene_to } ];
}
}
}
}
}
21 seconds
Previous version (with subroutine call):
use strict;
use warnings;
use List::Util qw(max min);
use Time::HiRes qw(time);
# this builds a structure that is usually retrieved from disk.
# in this example we will use this structure again and again,
# but in the real program we obviously retrieve a fresh structure
# at each iteration
my $simulation_h = {};
for ( 1 .. 70000 ) {
my $random_start = int( rand(5235641) );
my $random_length = int( rand(40000) );
push @{ $simulation_h->{$random_start} }, $random_length;
}
my $zone_o = {
_chromosome_length => 5235641,
_legal_range => [ { FROM => 100000, TO => 200000 } ]
};
my $start_time = time;
scenario();
print "total loop time: " . ( time - $start_time ) . " seconds\n";
my $temp_gene_to_legal_range;
my $gene_to;
sub scenario {
for ( my $i = 0 ; $i < 50 ; $i++ ) {
print "i=$i time=" . ( time - $start_time ) . " seconds\n";
# originally there was a retreive of $simulation_h from disk h
+ere
# iterate genes
foreach my $gene_from ( keys %{$simulation_h} ) {
foreach my $gene_length ( @{ $simulation_h->{$gene_from} }
+ ) {
#### inlining gene_to_legal_range
# $gene_to =
# ( ( $gene_from + $gene_length - 1 )
# % ( $zone_o->{_chromosome_length} ) ) + 1;
#
# if ( $gene_to < $gene_from ) {
#
# # split
# # low range first
# $temp_gene_to_legal_range = [
# { FROM => 0, TO => $gene_to },
# {
# FROM => $gene_from,
# TO => $zone_o->{_chromosome_length}
# }
# ];
# }
# else {
#
# # single
# $temp_gene_to_legal_range =
# [ { FROM => $gene_from, TO => $gene_to } ];
# }
#
# next; ####
$temp_gene_to_legal_range =
gene_to_legal_range( $gene_from, $gene_length,
$zone_o->{_chromosome_length} );
}
}
}
}
sub gene_to_legal_range($$$) {
return;
my ( $gene_from, $gene_length, $legal_length ) = @_;
my $ret;
my $gene_to = ( ( $gene_from + $gene_length - 1 ) % ($legal_length
+) ) + 1;
if ( $gene_to < $gene_from ) {
# split
# low range first
$ret = [
{ FROM => 0, TO => $gene_to },
{ FROM => $gene_from, TO => $legal_length }
];
}
else {
# single
$ret = [ { FROM => $gene_from, TO => $gene_to } ];
}
return $ret;
}
7.5 seconds
|