• 在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();
  • 相关阅读:
    基于python的socket网络编程
    Python3报错:ModuleNotFoundError: No module named '_bz2'
    机器学习博客网站
    《Linux内核设计与实现》 读书笔记(4)--进程的调度
    k8s 简单入门
    docker 简单入门
    python3 教程
    .toml 文件简介
    编码规范
    python3 基本用法
  • 原文地址:https://www.cnblogs.com/SuperChan/p/10256892.html
Copyright © 2020-2023  润新知