在Linq的Where條件中,如何優雅的進行類型轉換?


大家應該都知道Int32.Parse()是不安全,但有時可能會有僥幸心理,而我正是在這樣的心理驅使下,這么干了。相關場景簡化處理后的代碼,如下。

            List<BookInfo> bookLst = new List<BookInfo>();
            for (var i = 0; i < 100000000; i++)
            {
                bookLst.Add(new BookInfo() {
                    Num = i.ToString()
                });
            }

            //原有寫法
            var finalBookLst1= bookLst.Where(p => Int32.Parse(p.Num) > 10).ToList();

          public class BookInfo
          {
             public string Num { get; set; }
          }

很顯然,在linq的where條件之中,直接進行類型轉換是不安全的,基於此我們需要對這段代碼進行優化。
既然是對集合進行操作,那么我們可以使用for循環,來替代原有的where條件,因此便有了下面一段代碼。

            var finalBookLst2= new List<BookInfo>();
            for (var j = 0; j < bookLst.Count; j++)
            {
                int num1;
                Int32.TryParse(bookLst[j].Num,out num1);
                if (num1 > 10)
                    finalBookLst2.Add(bookLst[j]);
            }

在上述代碼中,我們直接遍歷集合中的每一個對象,對其進行業務判斷后,將滿足條件的對象加入到預期結果的集合之中,最后我們便得到了最終的結果。
用for循環寫完之后,我的第一想法就是這多low呀,性能得多差呀。於是乎經過了一番百度,我們的第二個方案便產生了。

            ConcurrentBag<BookInfo> finalBookLst3 = new ConcurrentBag<BookInfo>();
            Parallel.For(0,bookLst.Count,(num)=> {
                int num2;
                Int32.TryParse(bookLst[num].Num,out num2);
                if (num2 > 10)
                    finalBookLst3.Add(bookLst[num]);
            });

Parallel主要用於任務的並行執行,在上面的示例中,我們將我們業務判斷通過Parallel並行執行,希望能夠優化響應時間。但是,悲催的是,使用Parallel的方案更加耗時。
從以上示例可以看出,並行執行並不一定比串行執行效率高,因為並行執行是有額外開銷。同時需要支出的是,List是線程不安全的,因此我們使用ConcurrentBag<T>來保存處理結果。
而對於bookLst的訪問,由於不存在資源競爭,所以是安全。
木得辦法,由於Parallel性能太差,我們是要舍棄這種方案的,想要替代for循環還得另尋它法,最后便有了如下代碼的產生,這也是我們最終選擇的方案。

       private static bool CheckNum(BookInfo bookInfo)
        {
            int num;
            Int32.TryParse(bookInfo.Num, out num);
            if (num > 10)
                return true;
            else
                return false;
        }
       
        var finalBookLst4 = bookLst.Where(new Func<BookInfo,bool>(CheckNum)).ToList();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM