http://www.perlmonks.org?node_id=1216384


in reply to Re^2: (Easy Perl concurrency with MCE)
in thread Why should any one use/learn Perl 6?

You sure as hell don't need Cuckoo, errr, notPerl "6", or anything other than Perl to write clean, fast, correct, parallel code that can be used today in performance-critical environments, aka Real Life.

Why can't you just be positive? Always so negative!

I hadn't heard about MCE yet. By the looks of it, it has taken the ideas I had when I implemented the forks and ThreadPool modules to the next level. Kudos to Mario Roy.

Now to get back to your example, but then in Perl 6:

use MyClient; my $client = MyClient.new; my $list = $client.call('ListCustomers'); $list.parse_json_payload; say "Start: Found $list.payload.totalCount() accounts"; my %results; for $list.payload.items -> $account { my $id = $account.id; say "Deleting $id"; my $call = $client->call('DeleteCustomer', account_id => $id); say 'Status: ' . $call.status; $call.status == 204 ?? %results<OK>++ !! %results<NOT_OK>++; } say "Results: %results.perl()"

To make this run on multiple CPU's, one basically needs to do only one thing: prefix the for with a hyper;

hyper for $list.payload.items -> $account {

There is however one caveat: hashes in Perl 6 are not thread safe in the sense that they might lose updates when being updated from multiple threads. If you're just interested in number of successes / fails, why not make it two counters instead of elements in a hash? When updating integers from multiple threads, you should use atomic integers (otherwise you would have the same problem as with the hash elements). So the code becomes:

use MyClient; my $client = MyClient.new; my $list = $client.call('ListCustomers'); $list.parse_json_payload; say "Start: Found $list.payload.totalCount() accounts"; my atomicint $ok; my atomicint $not-ok; hyper for $list.payload.items -> $account { my $id = $account.id; say "Deleting $id"; my $call = $client->call('DeleteCustomer', account_id => $id); say 'Status: ' . $call.status; $call.status == 204 ?? atomic-inc-fetch($ok) !! atomic-inc-fetch($ +not-ok) } say "Results: ok = $ok, not-ok = $not-ok"

I've used the ASCII equivalent of the atomic increment operator, since PerlMonks does not display the unicode equivalent "++⚛️" inside code blocks properly.

So I would argue three things here:

  1. Perl 6 has less boilerplate to begin with (no use statements needed)
  2. Perl 6 needs less boilerplate to parallelize (just adding "hyper" will do in many cases
  3. Some thought needs to go into updating data structures from multiple threads at the same time

Note that the Perl 5 solution to updating shared data structures requires tieing and locking, neither of which is good for performance. The Perl 6 solution using atomic increment is lockless and uses hardware features of the CPU.

Hope this clarifies.

EDIT: fixed $results{} -> %results<> non-migrato, haj++

Replies are listed 'Best First'.
Re^4: Why should any one use/learn Perl 6?
by haj (Hermit) on Jun 11, 2018 at 13:47 UTC

    I'd have expected Perl 6 to have less boilerplate than Perl 5 for parallel processing. It's just that the advantage is smaller when you know about MCE than when you try to figure all of that out with Perl 5 core. So this is a Perl 6 benefit in the same order of magnitude as with objects, where I need to use Moose; in Perl 5 to get the object magic.

    Two minor nitpickings:

    • $call.status == 204 ?? $results<OK>++ !! $results<NOT_OK>++; seems somewhat Perl5ish. Shouldn't that read like that:
      $call.status == 204 ?? %results<OK>++ !! %results<NOT_OK>++;
    • You write: "I've used the ASCII equivalent of the atomic increment operator, since PerlMonks does not display the unicode equivalent "++⚛️" inside code blocks properly.". I'm glad you did, because this is another example why I don't like these unicode operators: I have no idea how to enter it into my keyboard easily, and my preferred font in my preferred editor doesn't have a glyph for it. There also seems to be another, quite similar symbol: "++⚛" which has an almost identical glyph in the textarea field into which I'm typing right now. I am pretty sure that I'll never use these symbols, and I hope I'll never need to maintain code which contains them.
      ...why I don't like these unicode operators: I have no idea how to enter it into my keyboard easily...

      FWIW, those characters live in my TouchBar on my MacBook Pro.

      ...my preferred font in my preferred editor doesn't have a glyph for it...

      That's not really a Perl 6 problem. I would say then that your preferred editor will have more and more problems surviving in a more and more unicodey world. Which of course means nothing about how useful it is in its current version for you and the type of work you do with it.

      In any case, Perl 6 has ASCII variants for all of its operators, so if you don't want to use them, then that's fine too!

        haj: ...why I don't like these unicode operators: I have no idea how to enter it into my keyboard easily...
        liz: FWIW, those characters live in my TouchBar on my MacBook Pro.

        So, should I hop over to the Netherlands and let you type the character or steal your MacBook Pro instead?

        I apologize for mocking you. This is going off-topic towards Unicode fine-print.

        I now know that some browsers don't even show the difference between the characters in question.

        What appears in your article is a ⚛️ character, which is not what you want to use in code. The difference between "⚛️" and "⚛" is that the former is one character composed of two codepoints: The atom symbol, U+269B, and the "VARIATION SELECTOR-16", U+FE0F. U+FEOF is a zero-width symbol which enforces emoji-style display for the preceding character. In Perl 6, "⚛️".chars is 1 and "⚛️".codes is 2.

        The correct character to be used in prefix ++⚛ is the plain atom symbol U+269B. In Perl 6, "⚛".chars is 1 and "⚛".codes is also 1.

        liz: That's not really a Perl 6 problem. I would say then that your preferred editor will have more and more problems surviving in a more and more unicodey world.

        In the past, one could create nasty Perl 6 code by assigning operators to zero-width symbols, but as far as I know this is no longer possible, so I agree, it is no longer a Perl 6 problem. On the other hand, I am actually really, really happy that my editor did display the atom symbol (for which it has a glyph) and the zero-width symbol (for which it displays a "FE0F" surrogate glyph) as two separate entities, so it was rather obvious why Perl 6 complained about a "Bogus postfix".

        For fun, try to type the following into a Perl 6 interactive shell, or feed it into the Perl 6 chat. Try to figure out which of the two fails before you paste it (Looking at the page source is considered cheating):

        • my atomicint $a = 1; $a⚛++; say $a
        • my atomicint $a = 1; $a⚛️++; say $a

        I am in awe about the depth of Unicode support in Perl 6, as far as data are concerned. But I am not so happy about its use in code.

        Maybe I'm just unlucky, but on my Windows desktop for work I couldn't get any of the standard fixed-width fonts to display this glyph. I tried it in both gvim and putty, with no luck.

        Does Perl 6 normalize the code points (like Unicode::Normalize) before it parses the code? haj might have answered that question

Re^4: Why should any one use/learn Perl 6?
by 1nickt (Abbot) on Jun 11, 2018 at 23:22 UTC

    "hashes in Cuckoo are not thread safe in the sense that they might lose updates when being updated from multiple threads"

    Oh, dear. Sounds like a rather significant deficiency compared to Perl, when we are discussing concurrency. (By the way, note that MCE does not require threads to parallelize.)

    "Note that the Perl 5 solution to updating shared data structures requires tieing and locking."

    Wrong. It does not.

    Why can't you just be positive? Always so negative!

    I'm negative about your project because it is still squatting on Perl's name, duh.


    The way forward always starts with a minimal test.
      "hashes in Cuckoo are not thread safe in the sense that they might lose updates when being updated from multiple threads" Oh, dear. Sounds like a rather significant deficiency compared to Perl, when we are discussing concurrency.

      Perl 6 has decided that it is not a good idea to shuffle the inherent problems of updating a data-structure like a hash from multiple threads at the same time, under the carpet. Tieing a hash with a Perl interface to make sure that all updates are done sequentially, is not a good step towards making a fully functional, and well performing threaded program without any bottlenecks. You, as a developer, need to be aware of the issues, and make adaptations to your program and/or the way you think about threaded programming.

      Think about writing your solutions as a pipeline, or using react whenever using an event driven model.

      In that sense, Perl 5 ithreads makes you a lazy programmer with everything being thread-local by default.

      "Note that the Perl 5 solution to updating shared data structures requires tieing and locking." Wrong. It does not.

      If I look at the code of MCE::Shared and MCE::Shared::Scalar, I do see things like a sub TIESCALAR, and &MCE::Shared::Scalar::new being bound to said TIESCALAR. That to me implies tieing. Or am I wrong?

      I'm negative about your project because it is still squatting on Perl's name, duh.

      I'm glad to hear that it's only the name you object to now.

        In that sense, Perl 5 ithreads makes you a lazy programmer

        Of course it does. Perl always encourages the three virtues.

        Greetings liz, MCE::Shared provides two interfaces OO and TIE. The OO interface does not involve TIE.

        Perl 6 has decided that it is not a good idea to shuffle the inherent problems of updating a data-structure like a hash from multiple threads at the same time, under the carpet. Tieing a hash with a Perl interface to make sure that all updates are done sequentially, is not a good step towards making a fully functional, and well performing threaded program without any bottlenecks. You, as a developer, need to be aware of the issues, and make adaptations to your program and/or the way you think about threaded programming.

        Think about writing your solutions as a pipeline, or using react whenever using an event driven model.

        As I understand this, there are two points you are making: shared hashes in Perl 6 are faster but not thread safe, and hashes are a bad choice of data structure for parallel programming.

        In cases where shared data is a better choice (no judgement here), isn't this a step backwards towards pthreads? In Perl 5 you're sure that at least the underlying data structure can't be corrupted (each thread has it's own interpreter) but in Perl 6 you need to take specific steps to ensure that it is not corrupted (threads share the same interpreter). I would think that with Perl 6, even with locking, you would still have better performance here since you aren't copying data between interpreters.

        Surely there is some middle ground between the Perl 5 threading model, pthreads, and the Python/Ruby GIL?

        I'm sure there is some nuance that I'm missing here. You have a lot more experience with threading than me, so maybe I'm just oversimplifying it and missing the point?

        Update: I found this blog post that discusses it. Still digesting it