Remix.run Logo
__red__ 2 days ago

There's a whole lot of discussion below so I'm just going to tag from here.

I think of pony actors in the same way as I think of erlang actors. They have a "mailbox", and when they receive a message, they wake up, execute some amount of code, and then go back to sleep.

This is how I think about it. This is not how it is actually implemented.

Here's the key that I think many people miss about pony.

Referential Capabilities DO NOT EXIST at runtime.

So let's talk passing a String iso from Actor A, to Actor B. (iso is the capability that guarantees that this is the only reference to this object):

  // This is code in Actor A
  actorB.some_behaviour_call(consume myisostring)

The "consume myisostring" completely removes myisostring from Actor A. Any reference to it after this point will result in an "unknown variable myisostring" error from the compiler.

The reference to myisostring then gets sent to Actor B via its mailbox.

If ActorB was idle, then the message receive will cause Actor B to be scheduled and it will receive the reference to that String iso - completely isolated.

Now, if we're going to measure "performance of passing data between threads" as latency per transaction, then actor contention on a scheduler is going to be a bigger factor.

If you're measuring performance across an entire system with millions of these actions occurring, then I would argue that this approach would be faster as there is no spinning involved.