简体   繁体   中英

Get a list of entities by list of guids

I am trying to get a partial list of entities for a list of entities by their guids.

could be accomplished by:

List<Entity> GetEntitiesByGuids (List<Entity> entities, List<Guids> guids)
{
  List<Entities> retVal = new List<Entities>();
     foreach(var guid in guids) 
     {
      var Entity = Entities.Find(e=>e.Guid ==guid)
      retVal.Add(Entity);
     }
return retVal;
}

Is there any nice way to do it without foreach ?

There is also a nice way of doing it WITH foreach:

IEnumerable<Entity> GetEntitiesByGuids (EntityList entities, List<Guids> guids)
{
     foreach(var guid in guids) 
     {
         yield return Entities.Find(e=>e.Guid ==guid);
     }
}

Performance-wise the best way of filtering list against another list is to use hashed collections because with hash we have fast lookup (that has complexity of almost O(1))

First let's measure time, required by using normal List<Guid> of hashes :

public static List<Entity> GetEntitiesByGuids(List<Entity> entities, List<Guid> guids)
{
    return entities?.Where(e => guids.Contains(e.Guid)).ToList();
}

And Main() method in both cases is :

var entities = new List<Entity>();
var guids = new List<Guid>();

for (int i = 0; i < 100000; i++) guids.Add(Guid.NewGuid());

for (int i = 0; i < 100000; i++) entities.Add(new Entity() {Guid = guids[i]});

var guidsToFilter = guids.Skip(12000).Take(40000).ToList();

Console.WriteLine("Started to filter list");

var s = new Stopwatch(); s.Start();

var result = GetEntitiesByGuids(entities, guidsToFilter);

s.Stop();

Console.WriteLine(s.ElapsedMilliseconds+"ms");

Result: 19823ms

Now let's introduce HashSet<T> collection :

public static List<Entity> GetEntitiesByGuids(List<Entity> entities, List<Guid> guids)
{
   var hashedGuids = new HashSet<Guid>(guids);        
   return entities?.Where(e => hashedGuids.Contains(e.Guid)).ToList();
}

Result: 11ms

List<Entity> GetEntitiesByGuids (List<Entity> entities, List<Guids> guids)
{
    List<Entities> retVal = entities.Where(e => guids.Contains(e.Guid)).ToList();
    return retVal;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM