[Dresden-pm] Lazy evaluation
Steffen Schwigon
schwigon at webit.de
Do Dez 20 00:45:28 PST 2007
Hi!
Weil wir's bei einem Treffen hatten und ich grad Lust hatte, hier mal
ein Beispiel an den Fibonacci-Zahlen, wie man lazy evaluation macht.
Wenn man $DO_LAZY auf 1 setzt, ist das Array mit den Fibonacci-Zahlen
scheinbar sofort gefüllt, weil lazy. Erst beim Zugriff auf die
Elemente, fängt er jedes Element an, zu berechnen.
Mit $DO_LAZY = 0 dauert das Vorbereiten des Arrays initial lange.
Interessanterweise scheint's entweder eine Optimierung in Perl für die
Rekursion zu geben, die ohne lazy effizienter ist, oder Scalar::Defer
bringt spürbaren Overhead mit. Jedenfalls kann ich ohne Lazy größere
Fibonacci-Zahlen schneller ausrechnen. Dafür halt nicht lazy.
lazy.pl
--------------------------------------------------
#! /usr/bin/perl
use Scalar::Defer; # exports 'defer', 'lazy' and 'force'
our $DO_LAZY = 1;
our $FIB_MAX = 26;
sub fib
{
my $n = shift;
return 1 if $n < 2;
if ($DO_LAZY) {
lazy { fib($n-1) + fib($n-2) };
} else {
fib($n-1) + fib($n-2);
}
}
print ~~localtime, " -- prepare fibs ... \n";
my @fibs = map { fib $_ } 0 .. $FIB_MAX;
print ~~localtime, " -- prepare finished \n";
print ~~localtime, " -- print array ... \n";
print "fib[$_] = ", $fibs[$_], "\n" for 0 .. $FIB_MAX;
print ~~localtime, " -- print array again ... \n";
print "fib[$_] = ", $fibs[$_], "\n" for 0 .. $FIB_MAX;
print ~~localtime, " -- Done\n";
--------------------------------------------------
GreetinX
Steffen
--
Steffen Schwigon <schwigon at webit.de>
Dresden Perl Mongers <http://dresden-pm.org/>
Deutscher Perl-Workshop <http://www.perl-workshop.de/>