[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/>