Hello folks! I have decided to implement the Game of Life in Unity for one of my projects and I found that the HashLife algorithm is one of the most efficient. I found following implementation based on Java. The algorithm almost entirely translates into C#. However, there is one problem I have encountered and that is the amount of garbage this accumulates when the pattern grows too chaotic. GC.Collect takes its tall to collect massive amount of garbage and produces a noticeable lag.
Shortly, to calculate the next generation, the nodes are created and are either safely retrieved from the hashmap (thus discarding new constructed instance) or saved as completely unique without being discarded. Each time the algorithm creates instances just to use them as keys. Here is an example of how a node is created using a factory method:
public override TreeNode Create(TreeNode nw, TreeNode ne, TreeNode sw, TreeNode se)
{
return new CanonicalTreeNode(nw, ne, sw, se).Intern();
}
With Intern() implementation being the code in question:
public TreeNode Intern()
{
if (hashMap.TryGetValue(this, out TreeNode canon))
{
return canon;
}
hashMap[this] = this;
return this;
}
As you can see, the algorithm always requires the instance to be created to at least serve as the key for the hash table. On a massive scale with > 10000 instances being created, this becomes unbearable.
It would be nice if the Create() method was the following instead:
public override TreeNode Create(TreeNode nw, TreeNode ne, TreeNode sw, TreeNode se)
{
return Intern(nw, ne, sw, se);
}
With Intern() method (pseudocode):
public TreeNode Intern(TreeNode nw, TreeNode ne, TreeNode sw, TreeNode se)
{
var key = GenerateKey(nw, ne, sw, se); //Some kind of key
if (hashMap.TryGetValue(key, out TreeNode canon))
{
return canon;
}
//Only then it would use the constructor!
canon = new CanonicalTreeNode(nw, ne, sw, se);
hashMap[key] = canon;
return canon;
}
My question is the following: is there any way I could still access the hash table without generating the new instance? The class has methods like Equals() and GetHashCode() overridden for collision management and that’s why I couldn’t simply replace the key with some kind of int.
Any help appreciated! And let me know if you need other info!