亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用IEqualityComparer加快許多字段的比較?

如何使用IEqualityComparer加快許多字段的比較?

C#
阿晨1998 2022-08-20 16:06:08
我在數據庫中有一個項目列表,我用以下方式檢索它:AE_AlignedPartnersList<AE_AlignedPartners> ae_alignedPartners_olds = ctx.AE_AlignedPartners.AsNoTracking().ToList();比,我得到并序列化了一個使用JSON的新列表(具有相同的對象類型):List<AE_AlignedPartners> ae_alignedPartners_news = GetJSONPartnersList();比我得到兩者的交集:var IDSIntersections = (from itemNew in ae_alignedPartners_news                        join itemOld in ae_alignedPartners_olds on itemNew.ObjectID equals itemOld.ObjectID                        select itemNew).Select(p => p.ObjectID).ToList();現在,由于這些交集,我需要檢查某些記錄是否已更改,檢查許多字段,然后添加到更新的“監視”列表中。代碼如下:IList<AE_AlignedPartners> ae_alignedPartners_toUpdate = new List<AE_AlignedPartners>();foreach (var item in IDSIntersections){    var itemOld = ae_alignedPartners_olds.First(p => p.ObjectID == item);    var itemNew = ae_alignedPartners_news.First(p => p.ObjectID == item);    if (itemOld.Field1 != itemNew.Field1 ||        itemOld.Field2 != itemNew.Field2 ||        itemOld.Field3 != itemNew.Field3 ||        itemOld.Field4 != itemNew.Field4 ||        itemOld.Field5 != itemNew.Field5 ||        itemOld.Field6 != itemNew.Field6 ||        itemOld.Field7 != itemNew.Field7 ||        itemOld.Field8 != itemNew.Field8 ||        itemOld.Field9 != itemNew.Field9)    {        AE_AlignedPartners toUpdate = mapper.Map<AE_AlignedPartners, AE_AlignedPartners>(itemNew);        toUpdate.ID = itemOld.ID;        ae_alignedPartners_toUpdate.Add(toUpdate);    }}這是非常慢的(發布約4分鐘,約70k條記錄)。最近我在這里發現了,它確實加快了比較的進程。IEqualityComparer在這種情況下,我可以利用它嗎?或者哪些是有效的優化?我不會使用建議的,因為這將意味著現在需要大量的重構(我將在下一個項目中這樣做,承諾)。FullOuterJoin有什么提示嗎?謝謝
查看完整描述

2 回答

?
千萬里不及你

TA貢獻1784條經驗 獲得超9個贊

您有嵌套循環實現


// O(N) : Loop over IDSIntersections

foreach (var item in IDSIntersections)

{

    // O(N) : Again, loop over ae_alignedPartners_olds

    var itemOld = ae_alignedPartners_olds.First(p => p.ObjectID == item);

    var itemNew = ae_alignedPartners_news.First(p => p.ObjectID == item);

    ...

在最壞的情況下,您將具有時間復雜性;數十億個循環: .讓我們借助字典擺脫內部循環:O(N) * O(N) = O(N**2)70k * 70k ~ 5e9


// O(N)

var dictOld = ae_alignedPartners_olds

  .GroupBy(p => p.ObjectID) // ObjectID should be a int, string or provide good GetHashCode()

  .ToDictionary(chunk => chunk.Key,

                chunk => chunk.First());


// O(N)

var dictNew = ae_alignedPartners_news

  .GroupBy(p => p.ObjectID) 

  .ToDictionary(chunk => chunk.Key,

                chunk => chunk.First());


// O(N)

foreach (var item in IDSIntersections)

{

   // O(1) : no loops when finding value by key in dictionary

   var itemOld = dictOld[item];      

   var itemNew = dictNew[item];

   ... 

現在我們將有關于循環:3 * O(N)3 * 70k ~ 2e5


查看完整回答
反對 回復 2022-08-20
?
慕哥9229398

TA貢獻1877條經驗 獲得超6個贊

自定義會很好,但不是因為它提高了性能,它需要做同樣的比較。但是因為在那里封裝邏輯使其更易于維護,可讀和可重用。您可以將其用于許多 LINQ 方法。IEqualityComparer<AE_AlignedPartners>


緩慢的是,您總是在 -循環中搜索舊項和新項。ObjectIdforeach


您不需要選擇兩者的共同點,如果您已經加入了舊的和新的,只需將整個實例存儲在匿名類型中:ObjectID


var intersections = from itemNew in ae_alignedPartners_news

                    join itemOld in ae_alignedPartners_olds on itemNew.ObjectID equals itemOld.ObjectID

                    select new { New = itemNew, Old = itemOld };


foreach(var x in intersections)

{

    var itemOld = x.Old;

    var itemNew = x.New;

    // ... 

}


查看完整回答
反對 回復 2022-08-20
  • 2 回答
  • 0 關注
  • 102 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號