I'm writing a 2D infinite Terrain Editor with focus on performance. Each time the user paints, he creates Nodes which at the moment are assigned to Dictionaries in "Layer" classes. Since the user can paint over existing nodes while he's on a different Layer, I want to find those nodes and destroy them. With my current setup this would involve looping through all the Layers and getting the necessary nodes one by one from the dictionaries.
Obviously, this is way too expensive if done tens of thousands of times per frame. So now I thought I could create just one Dictionary with all the nodes in lists. However, this turns out to use almost as much performance as the previous setup, because now I have to perform a check for whether a Key already exists when instantiating new Nodes :
before:
public Node(){ dic.Add(key,this); } now:
public Node(){ List<Node> nodes; if(dic.TryGetValue(key,out nodes)) nodes.Add(this); else{ list = new List<Node>(); dic.Add(key,list); } } As you can see, while the current setup saves some performance when checking for nodes, it completely ruins the effect by inflating the instantiation time by the dictionary lookup time.
So now I'm looking for some way to get the same effect as Dictionary<Key,List<Node>> , but without the cost of looking up the list in the dictionary. Is there perhaps a different type of dictionary that lets one stack an infinite (or if necessary a limited) number of Values per Key?
Alternatively, is it possible to somehow order the values in the dictionary so I could use a normal Dictionary<key, Node> and then look up the first key and loop from there through all the values until I hit some Node which no longer fits the search criteria?
In pseudo code, my instantiation functions would look like this :
public Node(){ dic.Add(key+LayerIndex,this); } and my lookup function would look something like this
public LookUpAll(key, out list){ var o = dic[key]; // looking up just one node list.Add(o); var keyPosition = o.keyPosition; while(o.position == keyPosition){ // then looping through all other nodes at that position until one comes that has a different position. o = dic.NextValue(); list.Add(o); } } Now, this does not work as is on the unsorted dictionary, but since I was hoping that someone here could maybe get some inspiration from it and work out a working solution.
How do I reduce the number of lookups in my scenario, or add multiple values per key without looking up the key first?