[英]Repeated where() vs multiple collections in c#
我有一個對象A的集合。 每個A都有一個與對象B相關的字段 - 我有另一個集合。 換句話說,每個B都附加到As集合的子集(但僅在概念上,而不是在代碼中)。 該字段 - 將A與B相關聯 - 可在系統壽命期間發生變化。 存在阻止改變該結構的系統要求。
如果我需要在每個B的A集上重復執行操作,那么重復使用A集合上的Where()方法或創建B擁有的另一個集合以及管理相關的添加和刪除的類會更好嗎項目。
讓我看看我是否可以在代碼中捕獲它:
class A {
public B owner;
...
}
class B {
...
}
class FrequentlyCalledAction {
public DoYourThing(B current) {
List<A> relevantItems = listOfAllAItems.Where(x => x.owner == current).ToList()
foreach (A item in relevantItems) {
...
}
}
}
VS:
class A {
public B owner;
...
}
class B {
public List<A> itsItems;
}
class FrequentlyCalledAction {
public void DoYourThing(B current) {
foreach (A item in current.itsItems) {
...
}
}
}
class AManager {
public void moveItem(A item, B from, B to) {
from.itsItems.remove(item);
to.itsItems.add(item);
}
}
這主要取決於集合的大小。 如果只有少數項目,解決方案2帶來的開銷大於性能增益。
在這種情況下,我會使用解決方案一,因為它具有更好的可讀性並且管理起來不那么復雜。
如果集合中有數千個項目,我會選擇解決方案二 。 moveItems
方法是一個O(n)操作,但似乎在您的方案中有更多的讀取而不是寫入。 因此,您通過更結構化的設計獲得更多性能。
實際上,這完全取決於您的收藏的大小。 Sol 2更復雜但是對於大型收集來說更快,而sol1可以非常快地用於少於100/1000個左右的項目。
由於集合很小(約100項)並且它們經常變化(〜每4次迭代)這樣做,然后看看你是否有問題。
public DoYourThing(B current)
{
foreach(A item in listOfAllAItems.Where(a => a.owner == current))
{
...
}
}
我沒有看到將IEnumrable <A>轉換為IList <A>的任何意義。
如果這給你帶來性能問題我不認為AManager
是你最好的答案,雖然這可能取決於關系改變了多少。
如果你選擇解決方案2,可能值得使用HashSet而不是List。 HashSet對於Add和Remove是O(1),而List是O(1)用於Add和O(n)用於刪除。
另一種選擇是,A&B的用戶不需要記住使用AManager
:
static class GlobalDictionary
{
private static Dictionary<B,HashSet<A>> dictionary = new Dictionary<B,HashSet<A>>();
public static HashSet<A> this[B obj]
{
// You could remove the set and have it check to see if a Set exists for a B
// if not you would create it.
get {return dictionary[obj];}
set {dictionary[obj] = value;}
}
}
class A
{
private B owner;
public B Owner
{
get{ return owner;}
set
{
if (owner != null) GlobalDictionary[owner].Remove(this);
owner = value;
GlobalDictionary[owner].Add(this);
}
}
}
class B
{
public B()
{
GlobalDictionary[this] = new HashSet<A>();
}
public IEnumerable<A> Children
{
get
{
return GlobalDictionary[this];
}
}
}
我沒有試過這個,所以它可能需要一些調整,但你應該得到這個想法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.