[Vienna-pm] Vars in sub max {..}
Carl A. Schreiber
gooly at gmx.at
Fri Feb 3 04:07:37 PST 2006
Am Freitag, 3. Februar 2006 12:00 schrieb peter pilsl:
> Carl A. Schreiber wrote:
> > }
> > Angenommen, dieses max() ist Teil eines Moduls (use ..),
> > wann und wie oft wird $x angelegt, also ihr Speicherplatz reserviert..
> > bzw, wann wird dieser Speicherplatz wieder freigegeben?
> > ( einmal beim laden des Moduls ),
> > einmal bei der ersten Ausführung
> > jedesmal, wenn max aufgerufen wird
> > ( .. ?)
> > ?
>
> #!/usr/bin/perl -w
>
> foreach (1..100) {a($_)};
> sub a {
> my $x = shift;
> print \$x,"\n";
> }
>
>
> Man sieht, dass der Speicherplatz bei jedem Aufruf ein anderer ist, der
> sich aber auch mal wiederholen kann.
>
> Die genaue Funktion der Speicherfreigabe ist nicht nur Aufgabe von perl
> und keinesfalls deterministisch.
>
> Was fix ist:
> bei jedem Aufruf der sub wird $x neu erzeugt. An welchem Speicherplatz
> ist nach aussen zufällig. Bei Ende der sub wird $x wieder freigegeben
> und damit im perl-internen sinn auch zerstört.
> Wann der Speicherplatz jetzt tatsächlich freigegeben wird im Sinne von :
> jetzt dürfen andere threads/applikationen darauf zugreifen, ist viel
> schwieriger. Da gibts mal eine perl-interne "garbage-collection" aber
> auch OS-abhängige Prozesse. (bzw. auch abhängig von den verwendeten libs
> auf dem OS)
>
hmm - aber Danke! -
das würde bedeuten, diese Version ohne Hilfsvariablen wäre bei eine
24h-7d-Programm besser?
sub max {
$_[0] = pop;
foreach ( @_ ) { $_[0] = $_ if ($_ > $_[0]) }
}
max( $max, @Werte );
(Ich war überrascht, aber das geht, testprogramm ist unten ..
trotzdem, ist das irgendwie gefährlich?)
Anm1. zwar wäre wohl eigentlich korrekt:
sub max {
${$_[0]} = pop;
foreach ( @_[1 .. $#_ ] ) { ${$_[0]} = $_ if ($_ > ${$_[0]} ) }
}
und max( \$max, @Werte );
aber ist langsamer!
Anm2: unter man perlsub, "Private Variables via my()"
fand ich nur etwas über die visibility gefunden, aber nix wann sie und wie sie
sterben. zB zu Garbage collection gibts 2 kurze Sätze
#!/usr/bin/perl
use strict;
use warnings;
$|++;
use Time::HiRes qw ( time alarm sleep );
sub max1 {
my $x = shift;
foreach ( @_ ) { $x = $_ if ($_ > $x) }
return $x;
}
sub max2 {
${$_[0]} = pop;
foreach ( @_[1..$#_] ) { ${$_[0]} = $_ if ($_ > ${$_[0]}) }
}
sub max3 {
$_[0] = pop;
foreach ( @_ ) { $_[0] = $_ if ($_ > $_[0]) }
#return $_[0];
}
my ($nArray, $nTurns) = (0, 8, 100000);
my ($max,$start,$end);
srand(5);
for my $i ( 0 .. 10 ) {
my @A;
for ( 0 .. int(rand($nArray))+2 ) { push @A, rand(100);
}
$start = time;
for ( 0 .. $nTurns ) {
$max = -1;
$max = max1( @A );
}
$end = time;
printf "max1:\t%5.1f n:%2i => %.5f\n",$max,scalar @A, $end-$start;
$start = time;
for ( 0 .. $nTurns ) {
$max = -1;
max2( \$max, @A );
}
$end = time;
printf "max2:\t%5.1f n:%2i => %.5f\n",$max,scalar @A, $end-$start;
$start = time;
for ( 0 .. $nTurns ) {
$max = -1;
max3( $max, @A );
}
$end = time;
printf "max3:\t%5.1f n:%2i => %.5f\n\n",$max,scalar @A, $end-$start;
}
More information about the Vienna-pm
mailing list