ILookUp的使用場景

一、背景

經監控,標籤關係上報20w+的標籤關係處理耗時達到3800多秒。約一個小時

二、問題定位

  • 經排查定位到以下代碼耗時佔比最大
  • 這段代碼沒有涉及到任務數據庫及外部調用
  • 其中的_dataCount總共20w+,證明兩個foreach一共循環了20w+次

 

 

三、複雜度分析

1 外層Foreach循環複雜度分析

  • Foreach循環20w+次可知 循環的複雜度O(N)≈20w

 

2 內層GetDTO方法複雜度分析

  • 由於裏面的GetDTO涉及了4個FirstOrDefault(),最大的爲tagRelationsModels,其數據量也爲20w+
  • FirstOrDefault()源碼可知其內部也是根據foreach去查找,因此GetDTO方法的複雜度O(M)約等於20w
  • FirstOrDefault源碼如下

 

 3 總體複雜度分析

  • 總體的複雜度爲O(N*M)≈400億+的計算量

 

四、優化

 

1 降低總體複雜度

  • 由於外層Foreach的複雜度無法降低,因此主要優化內層GetDTO中的複雜度
  • 根據ILookUp源碼可知其複雜度爲O(log2M),20w+的數量在O(log2M)下≈18
  • 在儘量不改到原邏輯的情況下,將FirstOrDefault改爲ILookUp
  • ILookUp源碼如下

 

 

 

 

 

 

五、總結&數據對比

  • 優化後總體的複雜度爲O(N*log2M)≈360w的計算量
  • 總計算量由400億降至360萬
  • 由於此次優化額外引入了ILookUp,會臨時佔用一部分內存,所以也涉及到了空間換時間的問題

 

數據量
優化前
優化後
93000 1235秒 122秒
68000 368秒 96秒
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章