標籤:data 記憶體 new || des 資料量 主鍵 需求 list
lamdba 效能 由於工作中需要對大量資料進行快速校正,實驗採用讀入記憶體列表採用lamdba尋找來實現。詳細需求:實際讀入記憶體資料 50W條記錄主集資料,還包含約20個子集,子集最大記錄數300W條記錄。讀入記憶體,校正出結果5分鐘之內完成。測試資料讀入記憶體後佔用約2-3G記憶體。這裡測試了多線程讀取資料,但提速效果並不明顯。SQLServer有自己的SQL執行排隊機制(讀入資料過程遇到一個小插曲,讀入速度慢,佔用記憶體大,無意中發現是把人員照片流也讀入了記憶體。實現處理資料過程並不需要照片資訊。去掉後速度提升很大,佔用記憶體也縮小很多,以後遇到類似操作應提前排除這類情況了)資料校正指令碼由另一個同事寫的,開始拿到指令碼丟進去測試,結果半個小時也沒反應。果斷結束進程。然後就是痛苦的最佳化過程,曾經懷疑這樣的方式行不通。差不多用了兩周時間,達到5000個主集資訊10秒以內完成。50W資料也在3-5分鐘完成。最後完成100個並發測試。校正結果正常返回。一切OK現已正常上線使用。 以下是在本次資料校正實現過程中總結出來應注意的一些地方。 1、由原來資料庫校正改為記憶體校正,記憶體速度更快2、載入資料採用多線程載入3、主鍵使用整形加快查詢速度 這一點特別重要,速度提升很多。4、採用lamdba運算式尋找資料 用聯集查詢代替for迴圈5、根據資料量的大小採用分別採取線性尋找或二分尋找提高查詢速度6、共用資料只取一次,在整個校正中全域使用。並發測試 時發現 靜態類中的靜態屬性不是安全的 因為靜態類在記憶體中只有一份 去掉static 後多線程測試正常 以下為測試資料,及相關說明,可以直接忽略。感興趣的的可以看看。1、7萬條記錄A01.FindAll(x => !x.PersonStatus.In("01", "02", "03", "04"))迴圈尋找,共載入15298人,耗時:0.019519秒.A01.FindAll(x => !(x.PersonStatus == "01" || x.PersonStatus == "02" || x.PersonStatus == "03" || x.PersonStatus == "04"))迴圈尋找,共載入15298人,耗時:0.0284169秒. 2、3.3萬條記錄 x.CodeID == "ZB01"的有3300條記錄Codes.FindAll(x => x.CodeID == "ZB01" && (x.CodeItemName == "市轄區" || x.CodeItemName == "縣"))迴圈尋找,共載入287人,耗時:0.0139286秒.Codes.FindAll(x => x.CodeID == "ZB01" && (x.CodeItemName.In("市轄區", "縣")))迴圈尋找,共載入287人,耗時:0.0230568秒. 3、4000條記錄 codeIds有3300條記錄personTableList.A01.FindAll(x => !x.A0114.In(codeIds));A01 4000條記錄 迴圈尋找,共載入0人,耗時:0.1066983秒.A01 7萬條記錄 迴圈尋找,共載入0人,耗時:1.7386399秒.foreach (var A01 in personTableList.A01) { if (!codes.Exists(x => x.CodeItemID == A01.A0114)) { persons.Add(A01); } } 上面形式代碼,兩個列表都是7W條記錄時迴圈尋找,共載入75601人,耗時:55.4800723秒.迴圈尋找,共載入75601人,耗時:107.4412256秒. 3、A01.FindAll(x => x.W0111G == "")迴圈尋找,共載入183人,耗時:0.0039961秒.A01.FindAll(x => x.W0111G.IsSame(""))迴圈尋找,共載入183人,耗時:0.0307353秒. A01.FindAll(x => personIds2.IndexOf(x.PersonID)) 最快A01.FindAll(x => x.PersonID.In(personIds)) 第二A01.FindAll(x => personIds2.Contains(x.PersonID)) 第二 A01.FindAll(x => personIds2.Exists(p=>p == x.PersonID)) 最慢 聯集查詢 速度快var query = (from A14 in PersonData.A14 join A01 in PersonData.A01 on A14.PersonID equals A01.PersonID select new { A14.PersonID, A14.A1407, A01.A0141 }).ToList(); personIds = query.FindAll(x => x.A0141 > x.A1407)非常重要 主鍵欄位 整形欄位比字串快上百倍 線性尋找:Contains,Find,IndexOf都是線性尋找。二分尋找:BinarySearch,因為二分尋找必須是對有序數組才有效,所以尋找前要調用List的Sort方法。結論:如果List項的個數比較小,用線性尋找要略快於二分尋找,項的個數越多二分演算法優勢越明顯。可根據實際情況選用適合的尋找方式。測試資料2條耗時:0.0186627秒.二分耗時:0.0356611秒.
lamdba 效能測試 大資料記憶體尋找