Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Profiling in Perl


Example 1

Example 1: Profile output for Memoize.pm and fibonacci.pl.

Back to Article

	

	<font color="red"><i>output omitted</i></font>
            ================ SmallProf version 0.9 ================
             Profile of /usr/lib/perl5/site_perl/5.005/Memoize.pm      Page 10
       =================================================================
    count wall tm  cpu time line
        0 0.000000 0.000000     1:# -*- mode: perl; perl-indent-level: 2; -*-
        0 0.000000 0.000000     2:# Memoize.pm
        0 0.000000 0.000000     3:#
        0 0.000000 0.000000     4:# Transparent memoization of idempotent
        0 0.000000 0.000000     5:#
        0 0.000000 0.000000     6:# Copyright 1998, 1999 M-J. Dominus.
        0 0.000000 0.000000     7:# You may copy and distribute this program
        0 0.000000 0.000000     8:# same terms as Perl itself.  If in doubt,
        0 0.000000 0.000000     9:# write to [email protected] for a
        0 0.000000 0.000000    10:#
        0 0.000000 0.000000    11:# Version 0.62 beta $Revision: 1.17 $ $Date:
        0 0.000000 0.000000    12:
        0 0.000000 0.000000    13:package Memoize;
        0 0.000000 0.000000    14:$VERSION = '0.62';
        0 0.000000 0.000000    15:
        0 0.000000 0.000000    16:# Compile-time constants
      314 0.003152 0.030000    17:sub SCALAR () { 0 }
        4 0.000039 0.000000    18:sub LIST () { 1 }
        0 0.000000 0.000000    19:
        0 0.000000 0.000000    20:
        0 0.000000 0.000000    21:#
        0 0.000000 0.000000    22:# Usage memoize(functionname/ref,
        0 0.000000 0.000000    23:#               { NORMALIZER => coderef,
        0 0.000000 0.000000    24:#                 LIST_CACHE => descriptor,
        0 0.000000 0.000000    25:#
        0 0.000000 0.000000    26:
        0 0.000000 0.000000    27:use Carp;
        0 0.000000 0.000000    28:use Exporter;
        0 0.000000 0.000000    29:use vars qw($DEBUG);
        0 0.000000 0.000000    30:@ISA = qw(Exporter);
        0 0.000000 0.000000    31:@EXPORT = qw(memoize);
        0 0.000000 0.000000    32:@EXPORT_OK = qw(unmemoize flush_cache);
        0 0.000000 0.000000    33:use strict;
        0 0.000000 0.000000    34:
        0 0.000000 0.000000    35:my %memotable;
        0 0.000000 0.000000    36:my %revmemotable;
        0 0.000000 0.000000    37:my @CONTEXT_TAGS = qw(MERGE TIE MEMORY FAULT
        0 0.000000 0.000000    38:my %IS_CACHE_TAG = map {($_ => 1)}
        0 0.000000 0.000000    39:
        0 0.000000 0.000000    40:# Raise an error if the user tries to specify
        0 0.000000 0.000000    41:# tie for LIST_CACHE
        0 0.000000 0.000000    42:
        0 0.000000 0.000000    43:my %scalar_only = map {($_ => 1)} qw(DB_File
        0 0.000000 0.000000    44:
        1 0.000000 0.000000    45:sub memoize {
        1 0.000017 0.000000    46:  my $fn = shift;
        1 0.000017 0.000000    47:  my %options = @_;
        1 0.000014 0.000000    48:  my $options = \%options;
        0 0.000000 0.000000    49:
        1 0.000018 0.000000    50:  unless (defined($fn) &&
        0 0.000000 0.000000    51:   (ref $fn eq 'CODE' || ref $fn eq '')) {
        0 0.000000 0.000000    52:    croak "Usage: memoize
        0 0.000000 0.000000    53:  }
        0 0.000000 0.000000    54:
        1 0.000017 0.000000    55:  my $uppack = caller;  # TCL me Elmo!
        1 0.000008 0.000000    56:  my $cref;   # Code reference to original

            ================ SmallProf version 0.9 ================
             Profile of /usr/lib/perl5/site_perl/5.005/Memoize.pm      Page 11
       =================================================================
    count wall tm  cpu time line
        1 0.000012 0.000000    57:  my $name = (ref $fn ? undef : $fn);
        0 0.000000 0.000000    58:
        0 0.000000 0.000000    59:  # Convert function names to code references
        1 0.000182 0.000000    60:  $cref = &_make_cref($fn, $uppack);
        0 0.000000 0.000000    61:
        0 0.000000 0.000000    62:  # Locate function prototype, if any
        1 0.000014 0.000000    63:  my $proto = prototype $cref;
        1 0.000012 0.000000    64:  if (defined $proto) { $proto = "($proto)" }
        1 0.000015 0.000000    65:  else { $proto = "" }
        0 0.000000 0.000000    66:
        0 0.000000 0.000000    67:  # Goto considered harmful!  Hee hee hee.
        1 0.000541 0.000000    68:  my $wrapper = eval "sub $proto { unshift
        0 0.000000 0.000000    69:  # Actually I would like to get rid of the
        0 0.000000 0.000000    70:  # to be any other way to set the prototype
        0 0.000000 0.000000    71:
        0 0.000000 0.000000    72:# --- THREADED PERL COMMENT ---
        0 0.000000 0.000000    73:# The above line might not work under
        0 0.000000 0.000000    74:# semantics are broken.  If that's the case,
        0 0.000000 0.000000    75:#  my $wrapper = eval "sub {
        0 0.000000 0.000000    76:# Confirmed 1998-12-27 this does work.
        0 0.000000 0.000000    77:# 1998-12-29: Sarathy says this bug is fixed
        0 0.000000 0.000000    78:# However, the module still fails, although
        0 0.000000 0.000000    79:
        1 0.000017 0.000000    80:  my $normalizer = $options{NORMALIZER};
        1 0.000012 0.000000    81:  if (defined $normalizer  && ! ref
        0 0.000000 0.000000    82:    $normalizer = _make_cref($normalizer,
        0 0.000000 0.000000    83:  }
        0 0.000000 0.000000    84:
        1 0.000010 0.000000    85:  my $install_name;
        1 0.000014 0.000000    86:  if (defined $options->{INSTALL}) {
        0 0.000000 0.000000    87:    # INSTALL => name
        0 0.000000 0.000000    88:    $install_name = $options->{INSTALL};
        1 0.000018 0.000000    89:  } elsif (! exists $options->{INSTALL}) {
        0 0.000000 0.000000    90:    # No INSTALL option provided; use
        1 0.000014 0.000000    91:    $install_name = $name;
        0 0.000000 0.000000    92:  } else {
        0 0.000000 0.000000    93:    # INSTALL => undef  means don't install
        0 0.000000 0.000000    94:  }
        0 0.000000 0.000000    95:
        1 0.000010 0.000000    96:  if (defined $install_name) {
        1 0.000030 0.000000    97:    $install_name = $uppack . '::' .
        0 0.000000 0.000000    98: unless $install_name =~ /::/;
        0 0.000000 0.000000    99:    no strict;
        1 0.000026 0.000000   100:    local($^W) = 0;        # ``Subroutine
        2 0.000048 0.000000   101:    *{$install_name} = $wrapper; # Install
        0 0.000000 0.000000   102:  }
        0 0.000000 0.000000   103:
        1 0.000067 0.000000   104:  $revmemotable{$wrapper} = "" . $cref; #
        0 0.000000 0.000000   105:
        0 0.000000 0.000000   106:  # These will be the caches
        1 0.000013 0.000000   107:  my %caches;
        3 0.000059 0.000000   108:  for my $context (qw(SCALAR LIST)) {
        0 0.000000 0.000000   109:    # suppress subsequent 'uninitialized
        2 0.000059 0.000000   110:    $options{"${context}_CACHE"} ||= '';
        0 0.000000 0.000000   111:
        2 0.000041 0.000000   112:    my $cache_opt =

            ================ SmallProf version 0.9 ================
             Profile of /usr/lib/perl5/site_perl/5.005/Memoize.pm      Page 12
       =================================================================
    count wall tm  cpu time line
        2 0.000021 0.000000   113:    my @cache_opt_args;
        2 0.000018 0.000000   114:    if (ref $cache_opt) {
        0 0.000000 0.000000   115:      @cache_opt_args = @$cache_opt;
        0 0.000000 0.000000   116:      $cache_opt = shift @cache_opt_args;
        0 0.000000 0.000000   117:    }
        2 0.000022 0.000000   118:    if ($cache_opt eq 'FAULT') { # no cache
        0 0.000000 0.000000   119:      $caches{$context} = undef;
        2 0.000021 0.000000   120:    } elsif ($cache_opt eq 'HASH') { # user-
        0 0.000000 0.000000   121:      $caches{$context} = $cache_opt_args[0];
        2 0.000023 0.000000   122:    } elsif ($cache_opt eq '' ||
        0 0.000000 0.000000   123:      # default is that we make up an in-
        2 0.000063 0.000000   124:      $caches{$context} = {};
        0 0.000000 0.000000   125:      # (this might get tied later, or MERGEd
        0 0.000000 0.000000   126:    } else {
        0 0.000000 0.000000   127:      croak "Unrecognized option to
        0 0.000000 0.000000   128:    }
        0 0.000000 0.000000   129:  }
        0 0.000000 0.000000   130:
        0 0.000000 0.000000   131:  # Perhaps I should check here that you
        0 0.000000 0.000000   132:  # options.  But if you did, it does do
        0 0.000000 0.000000   133:  # both get merged to the same in-memory
        1 0.000016 0.000000   134:  if ($options{SCALAR_CACHE} eq 'MERGE') {
        0 0.000000 0.000000   135:    $caches{SCALAR} = $caches{LIST};
        1 0.000017 0.000000   136:  } elsif ($options{LIST_CACHE} eq 'MERGE') {
        0 0.000000 0.000000   137:    $caches{LIST} = $caches{SCALAR};
        0 0.000000 0.000000   138:  }
        0 0.000000 0.000000   139:
        0 0.000000 0.000000   140:  # Now deal with the TIE options
        0 0.000000 0.000000   141:  {
        2 0.000023 0.000000   142:    my $context;
        3 0.000060 0.000000   143:    foreach $context (qw(SCALAR LIST)) {
        0 0.000000 0.000000   144:      # If the relevant option wasn't `TIE',
        2 0.000337 0.000000   145:      _my_tie($context, $caches{$context},
        0 0.000000 0.000000   146:    }
        0 0.000000 0.000000   147:  }
        0 0.000000 0.000000   148:
        0 0.000000 0.000000   149:  # We should put some more stuff in here
        0 0.000000 0.000000   150:  # We've been saying that for serveral
        0 0.000000 0.000000   151:  # And you know what?  More stuff keeps
        1 0.000092 0.000000   152:  $memotable{$cref} =
        0 0.000000 0.000000   153:  {
        0 0.000000 0.000000   154:    O => $options,  # Short keys here for
        0 0.000000 0.000000   155:    N => $normalizer,
        0 0.000000 0.000000   156:    U => $cref,
        0 0.000000 0.000000   157:    MEMOIZED => $wrapper,
        0 0.000000 0.000000   158:    PACKAGE => $uppack,
        0 0.000000 0.000000   159:    NAME => $install_name,
        0 0.000000 0.000000   160:    S => $caches{SCALAR},
        0 0.000000 0.000000   161:    L => $caches{LIST},
        0 0.000000 0.000000   162:  };
        0 0.000000 0.000000   163:
        1 0.000031 0.000000   164:  $wrapper   # Return just memoized version
        0 0.000000 0.000000   165:}
        0 0.000000 0.000000   166:
        0 0.000000 0.000000   167:# This function tries to load a tied hash
        2 0.000000 0.000000   168:sub _my_tie {

            ================ SmallProf version 0.9 ================
             Profile of /usr/lib/perl5/site_perl/5.005/Memoize.pm      Page 13
       =================================================================
    count wall tm  cpu time line
        2 0.000036 0.000000   169:  my ($context, $hash, $options) = @_;
        2 0.000039 0.000000   170:  my $fullopt = $options-
        0 0.000000 0.000000   171:
        0 0.000000 0.000000   172:  # We already checked to make sure that this
        2 0.000023 0.000000   173:  my $shortopt = (ref $fullopt) ? $fullopt-
        0 0.000000 0.000000   174:
        2 0.000050 0.000000   175:  return unless defined $shortopt &&
        0 0.000000 0.000000   176:
        0 0.000000 0.000000   177:  my @args = ref $fullopt ? @$fullopt : ();
        0 0.000000 0.000000   178:  shift @args;
        0 0.000000 0.000000   179:  my $module = shift @args;
        0 0.000000 0.000000   180:  if ($context eq 'LIST' &&
        0 0.000000 0.000000   181:    croak("You can't use $module for
        0 0.000000 0.000000   182:  }
        0 0.000000 0.000000   183:  my $modulefile = $module . '.pm';
        0 0.000000 0.000000   184:  $modulefile =~ s{::}{/}g;
        0 0.000000 0.000000   185:  eval { require $modulefile };
        0 0.000000 0.000000   186:  if ($@) {
        0 0.000000 0.000000   187:    croak "Memoize: Couldn't load hash tie
        0 0.000000 0.000000   188:  }
        0 0.000000 0.000000   189:#  eval  { import $module };
        0 0.000000 0.000000   190:#  if ($@) {
        0 0.000000 0.000000   191:#    croak "Memoize: Couldn't import hash tie
        0 0.000000 0.000000   192:#  }
        0 0.000000 0.000000   193:#  eval "use $module ()";
        0 0.000000 0.000000   194:#  if ($@) {
        0 0.000000 0.000000   195:#    croak "Memoize: Couldn't use hash tie
        0 0.000000 0.000000   196:#  }
        0 0.000000 0.000000   197:  my $rc = (tie %$hash => $module, @args);
        0 0.000000 0.000000   198:  unless ($rc) {
        0 0.000000 0.000000   199:    croak "Memoize: Couldn't tie hash to
        0 0.000000 0.000000   200:  }
        0 0.000000 0.000000   201:  1;
        0 0.000000 0.000000   202:}
        0 0.000000 0.000000   203:
        0 0.000000 0.000000   204:sub flush_cache {
        0 0.000000 0.000000   205:  my $func = _make_cref($_[0], scalar
        0 0.000000 0.000000   206:  my $info =
        0 0.000000 0.000000   207:  die "$func not memoized" unless defined
        0 0.000000 0.000000   208:  for my $context (qw(S L)) {
        0 0.000000 0.000000   209:    my $cache = $info->{$context};
        0 0.000000 0.000000   210:    if (tied %$cache && ! (tied %$cache)-
        0 0.000000 0.000000   211:      my $funcname = defined($info->{NAME}) ?
        0 0.000000 0.000000   212:          "function $info->{NAME}" :
        0 0.000000 0.000000   213:      my $context = {S => 'scalar', L =>
        0 0.000000 0.000000   214:      croak "Tied cache hash for $context-
        0 0.000000 0.000000   215:    } else {
        0 0.000000 0.000000   216:      %$cache = ();
        0 0.000000 0.000000   217:    }
        0 0.000000 0.000000   218:  }
        0 0.000000 0.000000   219:}
        0 0.000000 0.000000   220:
        0 0.000000 0.000000   221:# This is the function that manages the memo
        0 0.000000 0.000000   222:sub _memoizer {
       79 0.001108 0.000000   223:  my $orig = shift;  # stringized version of
       79 0.001127 0.000000   224:  my $info = $memotable{$orig};

            ================ SmallProf version 0.9 ================
             Profile of /usr/lib/perl5/site_perl/5.005/Memoize.pm      Page 14
       =================================================================
    count wall tm  cpu time line
       79 0.000889 0.000000   225:  my $normalizer = $info->{N};
        0 0.000000 0.000000   226:
       79 0.000639 0.020000   227:  my $argstr;
       79 0.012471 0.000000   228:  my $context = (wantarray() ? LIST :
        0 0.000000 0.000000   229:
       79 0.000763 0.000000   230:  if (defined $normalizer) {
        0 0.000000 0.000000   231:    no strict;
        0 0.000000 0.000000   232:    if ($context == SCALAR) {
        0 0.000000 0.000000   233:      $argstr = &{$normalizer}(@_);
        0 0.000000 0.000000   234:    } elsif ($context == LIST) {
        0 0.000000 0.000000   235:      ($argstr) = &{$normalizer}(@_);
        0 0.000000 0.000000   236:    } else {
        0 0.000000 0.000000   237:      croak "Internal error \#41; context was
        0 0.000000 0.000000   238:    }
        0 0.000000 0.000000   239:  } else {                      # Default
       79 0.091889 0.010000   240:    $argstr = join $;,@_;       # $;,@_;?
        0 0.000000 0.000000   241:  }
        0 0.000000 0.000000   242:
       79 0.012210 0.020000   243:  if ($context == SCALAR) {
       78 0.001069 0.010000   244:    my $cache = $info->{S};
       78 0.000772 0.000000   245:    _crap_out($info->{NAME}, 'scalar') unless
       78 0.001056 0.010000   246:    if (exists $cache->{$argstr}) {
       38 0.001693 0.010000   247:      return $cache->{$argstr};
        0 0.000000 0.000000   248:    } else {
       80 0.004003 0.010000   249:      my $val = &{$info->{U}}(@_);
        0 0.000000 0.000000   250:      # Scalars are considered to be lists;
       40 0.000709 0.000000   251:      if ($info->{O}{SCALAR_CACHE} eq
        0 0.000000 0.000000   252: $cache->{$argstr} = [$val];
        0 0.000000 0.000000   253:      } else {
       40 0.000859 0.000000   254: $cache->{$argstr} = $val;
        0 0.000000 0.000000   255:      }
       40 0.003255 0.000000   256:      $val;
        0 0.000000 0.000000   257:    }
        1 0.000151 0.000000   258:  } elsif ($context == LIST) {
        1 0.000015 0.000000   259:    my $cache = $info->{L};
        1 0.000011 0.000000   260:    _crap_out($info->{NAME}, 'list') unless
        1 0.000014 0.000000   261:    if (exists $cache->{$argstr}) {
        0 0.000000 0.000000   262:      my $val = $cache->{$argstr};
        0 0.000000 0.000000   263:      return ($val) unless ref $val eq
        0 0.000000 0.000000   264:      # An array ref is ambiguous. Did the
        0 0.000000 0.000000   265:      # an array ref?  Or did we cache a
        0 0.000000 0.000000   266:      # an anonymous array?
        0 0.000000 0.000000   267:      # If LISTCONTEXT=>MERGE, then the
        0 0.000000 0.000000   268:      # so we know for sure:
        0 0.000000 0.000000   269:      return ($val) if $info->{O}{LIST_CACHE}
        0 0.000000 0.000000   270:      # Otherwise, we're doomed.  ###BUG
        0 0.000000 0.000000   271:      return @$val;
        0 0.000000 0.000000   272:    } else {
        2 0.000082 0.000000   273:      my $q = $cache->{$argstr} = [&{$info-
        1 0.000590 0.000000   274:      @$q;
        0 0.000000 0.000000   275:    }
        0 0.000000 0.000000   276:  } else {
        0 0.000000 0.000000   277:    croak "Internal error \#42; context was
        0 0.000000 0.000000   278:  }
        0 0.000000 0.000000   279:}
        0 0.000000 0.000000   280:

            ================ SmallProf version 0.9 ================
             Profile of /usr/lib/perl5/site_perl/5.005/Memoize.pm      Page 15
       =================================================================
    count wall tm  cpu time line
        0 0.000000 0.000000   281:sub unmemoize {
        0 0.000000 0.000000   282:  my $f = shift;
        0 0.000000 0.000000   283:  my $uppack = caller;
        0 0.000000 0.000000   284:  my $cref = _make_cref($f, $uppack);
        0 0.000000 0.000000   285:
        0 0.000000 0.000000   286:  unless (exists $revmemotable{$cref}) {
        0 0.000000 0.000000   287:    croak "Could not unmemoize function `$f',
        0 0.000000 0.000000   288:  }
        0 0.000000 0.000000   289:
        0 0.000000 0.000000   290:  my $tabent =
        0 0.000000 0.000000   291:  unless (defined $tabent) {
        0 0.000000 0.000000   292:    croak "Could not figure out how to
        0 0.000000 0.000000   293:  }
        0 0.000000 0.000000   294:  my $name = $tabent->{NAME};
        0 0.000000 0.000000   295:  if (defined $name) {
        0 0.000000 0.000000   296:    no strict;
        0 0.000000 0.000000   297:    local($^W) = 0;        # ``Subroutine
        0 0.000000 0.000000   298:    *{$name} = $tabent->{U}; # Replace with
        0 0.000000 0.000000   299:  }
        0 0.000000 0.000000   300:  undef $memotable{$revmemotable{$cref}};
        0 0.000000 0.000000   301:  undef $revmemotable{$cref};
        0 0.000000 0.000000   302:
        0 0.000000 0.000000   303:  # This removes the last reference to the
        0 0.000000 0.000000   304:  # my ($old_function, $memotabs) =
        0 0.000000 0.000000   305:  # undef $tabent;
        0 0.000000 0.000000   306:
        0 0.000000 0.000000   307:#  # Untie the memo tables if they were tied.
        0 0.000000 0.000000   308:#  my $i;
        0 0.000000 0.000000   309:#  for $i (0,1) {
        0 0.000000 0.000000   310:#    if (tied %{$memotabs->[$i]}) {
        0 0.000000 0.000000   311:#      warn "Untying hash #$i\n";
        0 0.000000 0.000000   312:#      untie %{$memotabs->[$i]};
        0 0.000000 0.000000   313:#    }
        0 0.000000 0.000000   314:#  }
        0 0.000000 0.000000   315:
        0 0.000000 0.000000   316:  $tabent->{U};
        0 0.000000 0.000000   317:}
        0 0.000000 0.000000   318:
        1 0.000000 0.000000   319:sub _make_cref {
        1 0.000019 0.000000   320:  my $fn = shift;
        1 0.000023 0.000000   321:  my $uppack = shift;
        1 0.000009 0.000000   322:  my $cref;
        1 0.000008 0.000000   323:  my $name;
        0 0.000000 0.000000   324:
        1 0.000012 0.000000   325:  if (ref $fn eq 'CODE') {
        0 0.000000 0.000000   326:    $cref = $fn;
        1 0.000014 0.000000   327:  } elsif (! ref $fn) {
        1 0.000019 0.000000   328:    if ($fn =~ /::/) {
        0 0.000000 0.000000   329:      $name = $fn;
        0 0.000000 0.000000   330:    } else {
        1 0.000025 0.000000   331:      $name = $uppack . '::' . $fn;
        0 0.000000 0.000000   332:    }
        0 0.000000 0.000000   333:    no strict;
        1 0.000021 0.000000   334:    if (defined $name and !defined(&$name)) {
        0 0.000000 0.000000   335:      croak "Cannot operate on nonexistent
        0 0.000000 0.000000   336:    }

            ================ SmallProf version 0.9 ================
             Profile of /usr/lib/perl5/site_perl/5.005/Memoize.pm      Page 16
       =================================================================
    count wall tm  cpu time line
        0 0.000000 0.000000   337:#    $cref = \&$name;
        2 0.000040 0.000000   338:    $cref = *{$name}{CODE};
        0 0.000000 0.000000   339:  } else {
        0 0.000000 0.000000   340:    my $parent = (caller(1))[3]; # Function
        0 0.000000 0.000000   341:    croak "Usage: argument 1 to `$parent'
        0 0.000000 0.000000   342:  }
        1 0.000010 0.000000   343:  $DEBUG and warn "${name}($fn) => $cref in
        1 0.000020 0.000000   344:  $cref;
        0 0.000000 0.000000   345:}
        0 0.000000 0.000000   346:
        0 0.000000 0.000000   347:sub _crap_out {
        0 0.000000 0.000000   348:  my ($funcname, $context) = @_;
        0 0.000000 0.000000   349:  if (defined $funcname) {
        0 0.000000 0.000000   350:    croak "Function `$funcname' called in
        0 0.000000 0.000000   351:  } else {
        0 0.000000 0.000000   352:    croak "Anonymous function called in
        0 0.000000 0.000000   353:  }
        0 0.000000 0.000000   354:}
        0 0.000000 0.000000   355:
        0 0.000000 0.000000   356:1;

	
	<font color="red"><i>output omitted</i></font>

            ================ SmallProf version 0.9 ================
                              Profile of fibonacci.pl                      Page 28
       =================================================================
    count wall tm  cpu time line
        0 0.000000 0.000000     1:#!/usr/bin/perl
        0 0.000000 0.000000     2:
        0 0.000000 0.000000     3:use Memoize;
        0 0.000000 0.000000     4:
        1 0.000204 0.000000     5:memoize('fibonacci');
        0 0.000000 0.000000     6:
        0 0.000000 0.000000     7:sub fibonacci
        0 0.000000 0.000000     8:        {
       41 0.000663 0.000000     9:        my $index = shift;
        0 0.000000 0.000000    10:
       41 0.000446 0.000000    11:        return 0 if $index == 0;
       40 0.000395 0.000000    12:        return 1 if $index == 1;
        0 0.000000 0.000000    13:
       39 0.002819 0.000000    14:        return fibonacci( $index - 1 ) +
        0 0.000000 0.000000    15:        }
        0 0.000000 0.000000    16:
        1 0.000078 0.000000    17:print "F($ARGV[0]) is ", fibonacci($ARGV[0]),
        0 0.000000 0.000000    18:
        0 0.000000 0.000000    19:__END__	
        


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.