in reply to Re^10: rough approximation to pattern matching using local (Multi Subs)
in thread rough approximation to pattern matching using local

P6 will pretty much always need to inspect every parameter to a function call at runtime in order to determine which multi-sub to invoke.

Aiui P6 by design, and Rakudo in actuality, pretty much always resolve the dispatch target of a call with multisub candidates at compile-time, not run-time. See my previous comment in this thread for more details.

My overall point is that adding the syntactic convenience of multi-subs to P6 -- which will probably never be able to benefit from such optimisations -- is another nail in its coffin for programming where performance is important.

If you've read the comment I linked above you've hopefully switched to accepting that P6 multisubs in general, and as they have been used in P6 code to date, appear to perform roughly the same, speed-wise, as non multi subs in current Rakudo.

You've hopefully also seen why I think a literal parameter is supposed to be considered a singleton value, which in turn is acceptable as a finite set of values, which in turn enables the multisub resolution to stay compile-time. And why this isn't yet the case with Rakudo.


Even assuming that most multisub dispatches (in P6) are resolved at compile-time (and are thus no slower than non multi sub dispatches in P6), something about sub dispatching and calling in P6 leads to it being -- at least in my tests in this thread -- one or two orders of magnitude slower than perl (5) sub dispatches. Why?

One reason is missing optimizations. While Rakudo has been getting faster most months for years, the classic optimization phases and mechanisms now built in to Rakudo, NQP and MoarVM only landed last year. Folk have to actually use them to add the thousands of significant optimizations that are possible. Jonathan is wisely leaving these for others to pick off at their leisure while he focuses on stuff that realistically only he can do. Can sub dispatch get a whole lot faster? My guess is yes, way faster, but I'll investigate that guess and report back here on what I hear is possible.


Could P6 deliver value for some applications where performance is important? Several P6ers have written video games with Rakudo and I assure you they all think (enough) performance is very important! :) But seriously, I agree that Rakudo doesn't currently look like a strong candidate for writing high performance computing applications. To put it mildly. :)


Some news about incremental improvements:

  • Comment on Re^11: rough approximation to pattern matching using local (Multi Subs)

Replies are listed 'Best First'.
Re^12: rough approximation to pattern matching using local (Multi Subs)
by BrowserUk (Patriarch) on Feb 05, 2015 at 04:15 UTC
    Aiui P6 by design, and Rakudo in actuality, pretty much always resolve the dispatch target of a call with multisub candidates at compile-time, not run-time. See my previous comment in this thread for more details.

    I accept that, if conditions are favourable to the compiler -- ie. when all the types involved in all the signatures of a multi-sub are of restricted, defined type Int, Str etc. -- and if the compiler will only accept those exact defined types (or their defined subtypes if any) as a signature match; then the compiler will be able to decide which of the multi-subs to call at any given call site, at compile time, by inspecting the types of the arguments at that call site.

    But, if a multi-sub set XXX(... ), has its various aliases defined in terms of combinations of Int & str ((say) XXX( int, int ), or XXX( int, Str ) or XXX( Str, Int ) or XXX( Str, Str )); and the user supplies those ints and strings both wrapped over in standard scalars; it is impossible to decide at compile-time which of the set needs to be called, because the only (compile-time) type information at the call site is XXX( scalar, scalar ); which could match any of them.

    Thus there are two compile time choices: 1) reject the scalars args at compile time as an unknown sub; 2) generate runtime code to inspect the scalars and decide if the values they contain can be construed as a match for any of the four subs.

    Of course any XXX( scalar, scalar ) can match the latter, as any scalar value can be rendered as a string; But equally a scalar string could contain a valid integer. That process of runtime value-typing becomes geometrically more costly in the number of parameter values that need to be inspected.

    So, unless library authors writing well-(type)defined APIs are allowed to reject use by lazy, ducktyping, dynamic language enjoying, users; or the compiler is going to come with built-in Psi; multi-subs will have to have a runtime component.

    Ie. Before calling one of the 4 type signatures above, it will first have to inspect the values in the parameters and ask "Can this pair of runtime values be construed as a match", for each of the four subs in turn.

    And importantly, it will have to consider each of the signatures strictly in the order that the author wrote them in the source; thus denying it another optimisation used by compiled and semi-compiled, strongly typed languages supporting pattern matching.

    Does anyone reading this enjoy hacking on an optimizing compiler? :)

    Things certainly seem to have come on leaps and bounds in the last year or so, but I would say that you are still at the point of writing "a compiler" rather than an "optimising compiler".

    And the types of optimisations you are (still) looking for at this stage are; the right, possibly as-yet-unknown, efficient algorithms to implement some of Perl6's more esoteric features, along with some of those powerful features drawn from languages with strong typing and deep analysing compilers.

    Ie. algorithmic optimisation rather than implementation optimisation; and certainly not yet a the stage of peep-holing or JITing. (Which is a good thing relative to some of what went on in the past!)

    Maybe MoarVM will be able to stick to the asm.js subset and so gain from the amazing performance that can produce when combined with the latest js engines.

    My fears remain that several Perl6 features; and especially certain combinations of those features -- eg. multi-subs taking Junctions and selecting on their runtime states -- leave me with literally no ideas of how you could begin to code them efficiently. Before you can optimise something, you have to have a clear idea of how something works, and some of those combinations simply leave me with a complete vacuum as far as ideas are concerned. And that's despite years of thought and the occasional bit of research.

    I still wish the project success. I still have my doubts as to what is achievable.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
    In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
      As explained in another comment in this thread, multisub dispatch is generally compile-time resolution. (Aiui public multimethod dispatch is, in contrast, always run-time.) There's no need to add explicit types to the call args. Overall the P6 design is in much better shape than you are imagining.

      Imo one can usefully view Perl 6 as a compiled language with static nominal typing and pattern matching that judiciously blends in some dynamic options. If that doesn't make sense to you, please check out Jonathan's new slide deck "Beyond dynamic vs static".

      Thanks for engaging me; hopefully we'll have some more productive exchanges this year. :)