Serialization and the concept of the ActorRef.
They both go hand in hand.
in Akka/NET, ActorRefs are contextual, they belong to a given ActorSystem.
This means that when they are serialized, the serializer needs to be able to know how to transfer and rebind this context on serialization and deserialization.
To make it more complex, ActorRefs can be embedded in other messages.
There are a few other primitives also that are contextual and serialized.
This limits the options you have in terms of serializers.
It also puts a massive tax on the framework in terms of maintenance.
ActorRefs are also "resolved" when deserialized, so the deserializing system has to figure out which actor is targeted.
This lookup is slow due to parsing and scanning of actors and their children.
This makes network communication speed suffer _a lot_.
The configuration DSL HOCON is also tightly integrated with the entire infrastructure, making it hard to reason about what is going on and what parts of the config the current piece of code actually sees.
Akka/NET also lacks good interception points, its hard to hook into actors and monitor them.
So the issues are really both on a performance level and at a maintenance level.
The mindset in Akka.NET have been more "lets build everything ourselves from scratch to match the JVM" and in proto.actor "lets re-use proven tech and glue them together, with minimal code"
Founder of both Akka.NET and Proto.Actor here.
Right now, Proto.Actor-dotnet should not be trusted more than Akka.NET.
Akka.NET is production ready and has a huge community. has commercial support etc.
There are however a fair number of design issues that I dislike personally which led me to start Proto.Actor
The .NET implementation of proto.actor is in alpha version right now.
We are building and stabilizing the Go version first, which already is used in major production systems.
Akka.NET suffers from problems with the Helios transport right now, I don't think the Helios transport do more than a few thousand messages per sec ATM.
That being said, there is a new transport coming in Akka.NET 1.5 where we do 100 000 messages per sec in our experiments, so that is a huge improvement.
But that is still more than 8 times slower than GAM.
The reason for Akka.NET (and JVM Akka) having trouble in this area is that every message comes with a sender ActorRef that needs to be resolved. even if the target doesn't touch that ActorRef.
The serialization mechanism there is also a lot more complicated.
Akka.net wasnt really intended to be a complete port from the start, it was a weekend hack from my part that then grew into what later became akka.net when Aaron joined (akka.actor and akka.remote first).
Then things took off and it got a life of its own.
Now there is an entire sub-ecosystem growing around it in terms of persistence providers, testkits and dependency injection lib integrations.
AWESOME to see :)
Retlang was a pioneer in this space for .NET, sadly it never took off more than some initial hype.
But compared to Akka.NET, Akka on the JVM is battle proven for many years now, running backends for Wallmart, LinkedIn etc. So it is good ground to stand on.
Also, Akka.NET compared to Retlang, if I recall correctly, Retlang did about 300 k messages per sec locally, while Akka.NET does 34+ million messages per sec on the same laptop.
Roger Alsing the author of that old gimmic here :-)
Some clarifications from my part here, 4 years after the post was released:
1) No this does not qualify as a true GA/GP.
by definition GP need to have an computational AST, EvoLisa has an declarative AST.
There is also no cross over in play here.
(see 3* for explatation on this)
2) Hill climbing or not?
According to wikipedia, Hill climbing only changes _one_ value of the problem solving vector per generation.
""At each iteration, hill climbing will adjust a single element in X and determine whether the change improves the value of f(X)""
So it doesn't quite fit the hill climbing definition either, also the DNA/vector is of dynamic size in EvoLisa while Hill climbing AFAIK uses fixed size vectors (?)
3) Why wasn't a larger population used and why no cross over?
This is the part that most of you get wrong, increasing the population size and adding cross over will NOT benefit this specific problem.
The polygons are semi transparend and overlap, thus, adding/removing polygons will have a high impact on the fitness level, in pretty much every case in the wrong direction.
Let's use words as an example here:
organism1: "The Mona Lisa"
organism2: "La Gioconda"
Both may have similar fitness level, but completely different sets of polygons (letters in this naive example)
combining those will very very rarely yeild an improvement.
e.g. child(result of org1 and org2) "Lae Mocondisa" that is complete nonsense and the fitness level falls back to pretty much random levels.
Thus, you can just as well use pure mutation instead of cross over here.
If the problem instead had been based on genes that paint individual parts, e.g. a gene for the face, a gene for the background, a gene for the body etc.
THEN it would have made sense to use crossover.
In such case it would be possible to combine a good face gene with a good background gene and the fitness level would improve.
However, due to the nature of this specific problem where the polygons span the entire image, this is not effective.
And if crossover is not benefitial, then a larger population gets less interesting also since you cannot combine them.
Increasing the population will only make more separate individuals compete against eachother with no additative effect in any way.
see it like this.
If we have one sprinter running 100meters, if he might complete the run in about 10 sec.
If we add 1000 sprinters to the population, each of them might complete the run in about 10 sec each.
Thus, the problem is not solved any faster by adding more individuals here.
Also, by increasing the population size, there will be much more data to evaluate for each generation, so even if we can bring down the number of generations needed to solve the problem, the actual real world time to complete it would increase due to evaluation logic.
Anyway, nice to see that people still find this somewhat interesting.
It was pretty much a single evening hack back 4 years ago..
Serialization and the concept of the ActorRef. They both go hand in hand.
in Akka/NET, ActorRefs are contextual, they belong to a given ActorSystem.
This means that when they are serialized, the serializer needs to be able to know how to transfer and rebind this context on serialization and deserialization. To make it more complex, ActorRefs can be embedded in other messages. There are a few other primitives also that are contextual and serialized. This limits the options you have in terms of serializers. It also puts a massive tax on the framework in terms of maintenance.
ActorRefs are also "resolved" when deserialized, so the deserializing system has to figure out which actor is targeted. This lookup is slow due to parsing and scanning of actors and their children.
This makes network communication speed suffer _a lot_.
The configuration DSL HOCON is also tightly integrated with the entire infrastructure, making it hard to reason about what is going on and what parts of the config the current piece of code actually sees. Akka/NET also lacks good interception points, its hard to hook into actors and monitor them.
There are just too many moving parts for my own liking. I did blog about some of the problem areas in my POV about a year ago: https://rogerjohansson.blog/2016/03/13/random-things-learned...
So the issues are really both on a performance level and at a maintenance level.
The mindset in Akka.NET have been more "lets build everything ourselves from scratch to match the JVM" and in proto.actor "lets re-use proven tech and glue them together, with minimal code"