There are four issues raised by dominus' post and my response.

  1. Are Perl's function calls slow?

    The archetypal test of function call performance is the Ackermann Function. Go here to see the list of other languages that out-perform Perl for function call performance. Many of those are fully pre-compiled languages. Many are not.

    For comparison purposes, look at straight forward implementations in Perl, with the same in Java.

    Perl:

    P:\test\MJD>ack1 9 Ack(3,9): 4093 78.843 83.671 0 0
    Java:
    P:\test\MJD>timethis "c:javac ackermann.java && java ackermann 9" TimeThis : Command Line : c:javac ackermann.java && java ackermann 9 TimeThis : Start Time : Fri Sep 02 22:01:28 2005 Ack(3,9): 4093 TimeThis : Command Line : c:javac ackermann.java && java ackermann 9 TimeThis : Start Time : Fri Sep 02 22:01:28 2005 TimeThis : End Time : Fri Sep 02 22:01:29 2005 TimeThis : Elapsed Time : 00:00:01.031

    I've included the compilation and runtime for Java to even the score a little. JIT was not enabled.

    So 83.6 seconds for Perl, and 1.031 seconds for Java!

    Conclusion: Perl's function calls are slow.

  2. Is "Avoiding function calls because they are slow ... an absurd response to performance problems"?.

    Anyone whom visited that Shootout page may have noticed that there are two supplementary versions of the Perl implementation of the Ackermann function, besides the one used in the main body of the tests.

    These both run vastly more quickly than the main one

    • Ack2.pl run 92x faster than the standard perl version
    • Ack3.pl runs 474x faster.

    How do they succeed in achieving this performance.

    Ack2.pl uses (dominus's own) Memoize module. But how does this work?

    Adding a couple of lines to the test case:

    use Memoize; memoize("Ack"); my $count = 0; sub Ack { $count++; return $_[0] ? ($_[1] ? Ack($_[0]-1, Ack($_[0], $_[1]-1)) : Ack($_[0]-1, 1)) : $_[1]+1; } my $NUM = $ARGV[0]; $NUM = 1 if ($NUM < 1); my $ack = Ack(3, $NUM); print "Ack(3,$NUM): $ack"; #print times; print "Ack() called $count times";

    shows exactly how it achieves it's performance:

    P:\test\MJD>ack1 9 Ack(3,9): 4093 79.187 83.093 0 0 Ack() called 11,164,370 times P:\test\MJD>ack2 9 Ack(3,9): 4093 0.046000 Ack() called 12,294 times

    The performance is achieved by avoiding making function calls! 12,294 -v- 11,164,370

    And how does Ack3.pl achieve it's further gain in performance?

    By in-lining the caching and thereby further reducing the number of function calls, by avoiding those that Memoize wraps around the memoized function!

    Indeed, a substantial portion of dominus' book, High Order Perl deals with the very subject of eliminating recursion (p.229–53, 348 (from the index)).

    Conclusion: Avoiding function calls as a means of improving performance *is not* "...an absurd response..." to poor performance.

  3. Is "... the right response ... to try to fix the implementation" a feasible, practical suggestion?

    The number of people that have the required knowledge and expertise to dive into the perl sources to make this kind of change probably number in the low 10s.

    That's not to say that there isn't the possibility of scope for improvements. If you dump the assembler generated by an Inline C or XS function call and look at the number of times _Perl_get_context() is called in the prolog and epilog, there certainly seems to be the potential for some reduction. Of course, it may well be that a good optimising compiler succeeds in reducing some of the duplication, but that will vary from compiler to compiler and platform to platform.

    But a bunch of very clever guys have spent a good few years tuning the performance of Perl 5, and the idea that your average PerlMonk is going to do better than them any time soon, is .... (I'll leave the adjective to the individual reader to fill in).

    The idea that your average Perlmonk is likely to be able to go this route is overly optimistic at best. At worst, it is completely specious.

  4. Does my characterisation (of dominus' characterisation of the very techniques that his own module and book exploit as "absurd"), as "academic hot air" constitute a grievous insult?

    Others will draw their own conclusions, but for my part, I think that the idea that your average PerlMonk could adopt the suggestion "to improve the implementation" *is* academic.

    In that regard, dominus' voicing that suggestion, given his knowledge, expertise and history of exploiting the very technique he decried, *is* "hot air".

    Can a factual statement, regardless of the wording, be "an insult"?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.

In reply to Re^12: An apology is still in order by BrowserUk
in thread Performance, Abstraction and HOP by pg

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.