[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