Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: Performance, Abstraction and HOP

by Dominus (Parson)
on Sep 01, 2005 at 14:08 UTC ( [id://488379]=note: print w/replies, xml ) Need Help??


in reply to Performance, Abstraction and HOP

pg says:
Take Stream.pm as one example, its slowness should ring the bell.
Slow compared to what? For what purpose?

I want to say that I don't think that Stream.pm is "slow". But I don't know what you think you mean, so I cannot contradict you. After three years of teaching performance tuning classes at OSCON, the one thing I am sure I have learned from my research is that people are much too eager to say it's "too slow" when they don't really know what they mean by it.

For example, you might mean that it is slower than using arrays. But it doesn't do the same thing as arrays, so there is no reason to expect it to be as fast as arrays. Perl arrays are slower than C arrays. This is not a defect in Perl arrays. Perl arrays were not supposed to be as fast as C arrays; they were supposed to support push.

Another thing I learned from my research for the classes is that people pronounce things "slow" or "fast" without doing proper research, and with no regard for the real facts. Even when they do the research, benchmarking a tricky business. The tools are bad, and they are easy to misuse. One whole section of my class is nothing but examples of benchmarks that were written incorrectly and led the writer to the wrong conclusion. Some of those examples come from Perlmonks.

One more point occurs to me. This is that the techniques in my book are primarily based around using functions. If the techniques are slower than other techniques, it is probably because they call a lot of functions. If function calls are slow, that is not a problem with the techniques; it is a problem with the language implementation. Function calling is not a frill that you can avoid when you want extra speed; it is essential. Every program makes lots of function calls. Avoiding function calls because they are slow is an absurd response to performance problems. If Perl's function calls are slow, the right response is to try to fix the implementation, not to try to avoid function calls.

Replies are listed 'Best First'.
Re^2: Performance, Abstraction and HOP
by BrowserUk (Patriarch) on Sep 01, 2005 at 14:35 UTC
    If Perl's function calls are slow, the right response is to try to fix the implementation, not to try to avoid function calls.

    As someone with more than a passing familiarity with the internals of Perl 5, do you consider it feasible* to substantially improve the current performance of function calls?

    Update: *Given the nature of the forum, perhaps practical is a better word than feasible in this context.


    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.
      BrowserUk asks:
      Do you consider it feasible to substantially improve the current performance of function calls?
      Sorry, I do not have an informed opinion on that topic.

        If you don't have a clue, why should you make those pointless bogus statements in the first place.

        This is not a TV show, and nobody here is running for senator.

      A reply falls below the community's threshold of quality. You may see it by logging in.
Re^2: Performance, Abstraction and HOP
by demerphq (Chancellor) on Sep 08, 2005 at 11:20 UTC

    One more point occurs to me. This is that the techniques in my book are primarily based around using functions. If the techniques are slower than other techniques, it is probably because they call a lot of functions. If function calls are slow, that is not a problem with the techniques; it is a problem with the language implementation.

    I don't really agree with this. I mean, yes, if slow function calls are a problem then yes it is a language issue that really long term aught to be handled by fixing the implementation. But on the other hand we are engineers and problem solvers that have to work with the tools we have. So assuming that we have good reasons to use Perl, and assuming that functions are a problem then any technique that depends on them heavily is flawed in some situations when using the Perls that are available right now.

    Personally im in the camp that says that for some tasks Perl's method overhead and subroutine overhead becomes unacceptable. That may be because of the type of work I do (reasonably large scale data processing), but thats the way I view it. Now, what I think is really interesting are the techniques that allow you to have your cake and eat it too. So for instance I've found that constructing tailored code that doesnt use subroutine or method calls from a rule set implemented in OO is quite powerful. Each rule knows how to represent itself as a snippet, and once the rules are stiched together you get a single monolithic piece of code that performs very well. At the same time you get a clean conceptual model that you can work with at a higher level of abstraction.

    Anyway, I was hoping that HOP had stuff along this line but your response makes me think not. Nevertheless I still look forward to reading it. :-)

    ---
    $world=~s/war/peace/g

      Said demerphq:
      I mean, yes, if slow function calls are a problem then yes it is a language issue that really long term aught to be handled by fixing the implementation. But on the other hand we are engineers and problem solvers that have to work with the tools we have.

      Sure. But if Perl's function calls are "too slow", where does that leave you with Perl? You can't do functional-style programming, because that would use too many function calls. And you can't do object-oriented style programming, because that would also use too many function calls, and method calls are slower than regular function calls. And you can't write any big or complex programs, because big complex programs are full of functions and then they must be too slow.

      So where does that leave you? I think it leaves you with "Perl is just a scripting language, only good for throwaway scripts, but nothing big or important." Which some people do believe, but I do not.

      Basically, my argument is this: Some language features can be avoided, but functions are not one of those features. Some implementation deficiencies can be worked around, but if function calls are too slow, there is no workaround. Every nontrivial program must contain lots of function calls. So if Perl's function calls are "too slow" (whatever that means, and nobody in this thread has suggested any relevant meaning) then you have only two choices. One is to fix Perl. The other, as you said, is to be a problem-solving engineer, to recognize that you are in a hopeless situation, and to obtain a tool that is not hopelessly defective. I have recently been informed that Java's function calls are faster than Perl's; perhaps that would be a better choice.

      But it seems to me that you cannot reasonably hold the opinion that Perl is worth using for nontrivial programs and also that Perl's function calls are too slow to use.

      I found your description of "constructing tailored code..." etc. above really interesting, but I can't imagine what it looks like, or what you could be doing that the function-call overhead is the bottleneck. I can only imagine that what you are doing does not really make sense, or that it is such a weird special situation that it has little applicability to general discussions like this one. I suppose this is just a failure of my imagination, but I certainly would like to see it.

      Anyway, I was hoping that HOP had stuff along this line...

      Wouldn't it better if it had something in it that you hadn't already thought of?

        Wouldn't it better if it had something in it that you hadn't already thought of?

        No, I figure you are smarter than I am, and I know you are a better writer, so I figured if you covered the subject of dynamically generated code it would be well worth reading. :-)

        But it seems to me that you cannot reasonably hold the opinion that Perl is worth using for nontrivial programs and also that Perl's function calls are too slow to use.

        Of course that would be an unreasonable position. And Its not the position I hold. The position that I hold is that there are some task where Perls function call overhead starts to become unreasonable, and thus for those tasks I do what I can to avoid function calls. Eliminating them entirely is usually not feasable, but with a bit of cacheing (not ala Memoize.pm which is too slow -- yes ive benchmarked it) you can often minimize their impact.

        I can only imagine that what you are doing does not really make sense, or that it is such a weird special situation that it has little applicability to general discussions like this one.

        Well I'm talking about processing tens to hundreds of millions of records per program run. For instance every day a program I have has to apply a set of rules stipluated in an ini file to all of the records that we have recieved from the previous day. Exactly which rules apply to a record are determined based on criteria like the the type of file that is being processed.

        A naive implementation of code like this would have a single main loop and then a lot of conditional logic, checking to see which rules apply. In addition it would probably have the rule handling logic factored out into method calls and subroutines. The naive implementation will take a big speed hit just for the method calls.

        When I realized how large the speed hit was from the method calls i started looking into how I could unroll them, and dynamically generate the loop so that once it started all lookups were statically resolved. Thus each method knows how to represent itself as a snippet. Each rule object knows how to represent itself as an if statement, etc. The result is a considerably faster record processing engine. IOW, instead of writing a generic record processing tool, I wrote an engine that would produce a tailored record processing tool that would then do the processing.

        Ive used this technique quite succesfully a number of times, and normally I find that it provides a perfect compromise. In most parts of the code function all overhead is negligable. DB calls, file operations accross the network, etc are the bottlenecks, not the function call overhead. But inside of a tight loop that has to process millions of records per day, doing what I can to avoid unnecessary method and function calls has proved to be a powerful optimization technique.

        The other, as you said, is to be a problem-solving engineer, to recognize that you are in a hopeless situation, and to obtain a tool that is not hopelessly defective. I have recently been informed that Java's function calls are faster than Perl's; perhaps that would be a better choice.

        well, personally I never considered changing language, just squeezing more performance out of the one I have. If it seemed to me that I could not reach acceptable performance levels with Perl regardless of the techniques I used then I probably would have done so. But the truth is that Perl is pretty fast at a alot of things, and is flexible too. I usually am able to fairly easily avoid method and function calls when I need to, so I dont worry about it too much.

        And actually its amusing that you say to use Java, as thats one of the few languages that I actually havent seen used for any serious systems in my field. Apparently its just too slow. :-)

        ---
        $world=~s/war/peace/g

        Basically, my argument is this: Some language features can be avoided, but functions are not one of those features. Some implementation deficiencies can be worked around, but if function calls are too slow, there is no workaround. Every nontrivial program must contain lots of function calls. So if Perl's function calls are "too slow" (whatever that means, and nobody in this thread has suggested any relevant meaning) then you have only two choices. One is to fix Perl. The other, as you said, is to be a problem-solving engineer, to recognize that you are in a hopeless situation, and to obtain a tool that is not hopelessly defective.
        Maybe I'm not reading that right, but that sounds like a huge failure of imagination. Here's my recipe for writing programs. First, you should try make sure you're using a low complexity algorithm if there's one available (i.e. no exponentials or O(n**2), O(n**3), etc.). Then you code up the problem in a functional manner, in high level language like Perl. The test and debug it on small amounts of data. Then you try running it. If its not fast enough, profile it to identify the "inner loop", which might only be 5% of your code. If the "inner loop" is a recursive function, rewrite it in tail recursive form (using a manual stack if necessary) and implement it with a while loop, eliminating the function calls. Or maybe the problem calls for some manual inlining (also called fusion or deforestation). If its still not fast enough, write the inner loop in C. If that's not fast enough, then you need a faster machine. But in any case, you've still got the (debugged, tested) Perl version to test your other programs against. Here's some fine further reading to keep you motivated.
        So if Perl's function calls are "too slow" (whatever that means, and nobody in this thread has suggested any relevant meaning)
        ~/perl$ cat func_test.pl #!/usr/bin/perl #sum of number between 1 and 1,000,000 $n = 1_000_000; print addup($n, 0); sub addup { return $_[1] if !$_[0]; return addup($_[0]-1,$_[1]+$_[0]); } ~/perl$ cat loop_test.pl #!/usr/bin/perl #sum of number between 1 and 1,000,000 $n = 1_000_000; $sum = 0; $sum += $n-- while($n); ~/perl$ time ./func_test.pl 500000500000 real 0m4.025s user 0m3.568s sys 0m0.455s ~/perl$ time loop_test.pl real 0m0.390s user 0m0.388s sys 0m0.001s
Re^2: Performance, Abstraction and HOP
by Anonymous Monk on Sep 02, 2005 at 15:46 UTC
    If Perl's function calls are slow, the right response is to try to fix the implementation, not to try to avoid function calls.
    Or, if you can try the hybrid approach, and eat your cake as well as have it...
    But, if you study programming languages, you discover that although there is a problem, through a small number of correctness-preserving transformations, this problem can be averted. And by being aware of the problem, you can better appreciate the merits of languages that manage to avoid it.
Re^2: Performance, Abstraction and HOP
by Anonymous Monk on Sep 08, 2005 at 03:01 UTC

    Do your home work before you came here with flame. Do a super search, and you will find the OP did tested Stream.pm's performance Streams and "deep recursion" warning.

    The moment you put your module on CPAN, is just like the moment you entering a recruit office, you should expect what is in front of you. People will comment your module, good or bad. Go improve your module, before you start to be defensive. The truth is that that module is quite useless.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://488379]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (8)
As of 2024-04-23 12:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found