I have an Id mapping cache that’s taking up a bit too much memory. It’s used to house a combination of 3 different types of Id’s for an object and the mappings for them are read in from a table, and cached in 6 different dictionaries for quick look-up/translation from any 1 Id type to another (performance is important for my application).
I wanted to rewrite it to something that has a smaller memory footprint so I did implement a consolidated list of the Id’s and used a linq/lambda expression to pull out the values I wanted. It looks like this for now.
public struct IdMappings
{
public int Id1;
public int Id2;
public int Id3;
}
//new cache
private static List<IdMappings> AllIdMappings = null;
//current cache implementation
private static Dictionary<int, int> Id1ToId2 = null;
private static Dictionary<int, int> Id1ToId3 = null;
//etc.
public static void FillCache(DataSet data)
{
foreach (DataRow r in data.Tables[0].Rows)
{
//fill list and/or dictionaries with id's
}
}
Example lookup would then be:
public static int GetId2FromId1(int id1)
{
return AllIdMappings.FirstOrDefault(m => m.Id1 == id1).Id2;
//or
return Id1ToId2[id1];
}
This does what I need in terms of reducing memory usage, but performance for lookups has suffered as a result so I’m seeing how to implement something different. Is there a way to do multi-indexing keys, or multi-key lookup that’s relatively faster than iterating through a list?
If you add these three dictionaries:
And have the dictionary values be the same references, it should use minimally more memory but retain the same lookup speed as your original implementation.
If I’m thinking about this right, this should use half the memory of your 6 dictionary solution, but twice a
List<IdMappings>type solution.As @SWeko points out,
IdMappingsneeds to be aclassnot astructto ensure the reference pointer is used rather than copies of it.