Superlman has asked for the wisdom of the Perl Monks concerning the following question:

Let's say I have a loop as follows:
while($foo < &ReallyComplexFunction($bar)) { doStuff(); }
In which &ReallyConmplexFunction takes a few seconds to evaluate, and $foo changes with each iteration, but $bar may or may not. Since I don't know, I can't take &ReallyComplexFunction out and do something like
$foobar = &ReallyComplexFunction($bar) while($foo < $foobar) { doStuff(); }
...since $bar may change.

I was thinking it would be rather nifty if the results of a function were cached, so that if the function was called multiple times with the same input, the output would be nearly instantaneous after the first time. (Yes, I realize how undesirable this would be for the vast majority of functions- imagine if the results of time were cached!)

What would be an efficient way to do something like this? Does Perl have some kind of optimizer that renders my question pointless?

Replies are listed 'Best First'.
Re: Efficiency and Functions in loops
by suaveant (Parson) on Oct 11, 2001 at 22:09 UTC
    Try this...
    my %cache; while($foo < (exists $cache{$bar} ? $cache{$bar} : $cache{$bar} = &ReallyComplexFunction($bar))) { doStuff(); }
    Untested, but should work

    Update I just realized how funny $cache{$bar} is, if cache is pronounced correctly ;)

    Update2 Also remembered that there is a module to do this... Memoize

                    - Ant
                    - Some of my best work - Fish Dinner

Re: Efficiency and Functions in loops
by perrin (Chancellor) on Oct 11, 2001 at 22:18 UTC
    The Memoize module is the standard way to do this.
Re: Efficiency and Functions in loops
by blakem (Monsignor) on Oct 11, 2001 at 22:19 UTC
    Memoize makes that a snap!
    use Memoize; memoize('ReallyComplexFunction'); # everything else stays exactly the same....

    -Blake

Re: Efficiency and Functions in loops
by thinker (Parson) on Oct 11, 2001 at 22:20 UTC
    Hi Superlman,

    I think the memoize module does what you want.
    Check out the documentation at memoize

    cheers

    thinker.
Re: Efficiency and Functions in loops
by dragonchild (Archbishop) on Oct 11, 2001 at 22:10 UTC
    Perl doesn't do it automatically, but you can very easily cache it yourself.
    my %cache; while ($foo < $cache{$bar} ||= ReallyComplexFunction($bar)) { doStuff(); }

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      There is one caveat to your way, dragonchild, and that is if ReallyComplexFunction returns a 0 or '', or even undef, the ||= will see that as false and re-run the routine... may not be an issue, though...

                      - Ant
                      - Some of my best work - Fish Dinner

Re: Efficiency and Functions in loops
by George_Sherston (Vicar) on Oct 11, 2001 at 22:33 UTC
      Although slightly unclear from the dearth and diversity of the responses, I think Memoize might be worth investigating.

      -Blake