Reputation: 5367
I have implemented a very simple lookup-cache in order to optimize processing of some DB entities. The cache class looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SyncEngine.Caches
{
class TenantsCache : Cache
{
System.Collections.Generic.List<tenant> list;
public override void ReadFromDB()
{
using (var ctx = new MyContext())
{
this.list = ctx.tenants.ToList<tenant>();
}
}
public override void Add(object o)
{
list.Add((tenant)o);
}
public tenant LookupByFNandGID(string fn, int groupId)
{
tenant match = null;
foreach (tenant t in list)
{
if (t.friendlyName == fn && t.groupId == groupId) // <-- slowest line
{
match = t;
break;
}
}
return match;
}
}
}
By analyzing CPU usage, I see that this Lookup (specifically the highlit line ) takes the most amount of processing time.
Is there a better, significantly more efficient way to implement this lookup/cache and/or the comparison here? Is there a more efficient in-built Collection with optimized lookup by two fields?
Upvotes: 0
Views: 86
Reputation: 114
You can create Dictionary with a custom key that contains both fields:
class Key : IEquatable<Key>
{
public string fn;
public int groupId;
public override bool Equals(object obj)
{
Key k = obj as Key;
if (k == null)
{
return false;
}
else
{
return this.Equals(k);
}
}
public bool Equals(Key other)
{
return this.fn == other.fn && this.groupId == other.groupId;
}
public override int GetHashCode()
{
return fn.GetHashCode() * 13 + groupId.GetHashCode();
}
}
Then you can use a dictionary which is much faster for lookup than a list:
Dictionary<Key, tenant> foo = new Dictionary<Key, tenant>();
Upvotes: 3