zoukankan      html  css  js  c++  java
  • 短路逻辑和延迟加载

    一、短路逻辑

    短路逻辑(short-circuit logic)也叫懒惰求值(lazy evaluation),在我们熟知的布尔运算中有一个非常有趣的特性:只有在需要求值时才进行求值。举例来说,ConditionA() and ConditionB()需要两个条件都为真时才是真,所以如果ConditionA() 为假,表达式立刻返回false,而不会去计算ConditionB()造成不必要的运算浪费。

            static void Main(string[] args)
            {
                if (ConditionA() && ConditionB())
                {
                    System.Console.WriteLine("ConditionA() && ConditionB() is true");
                }
                System.Console.WriteLine("short-circuit logic test end");
                System.Console.Read();
            }
    
            static bool ConditionA()
            {
                System.Console.WriteLine("ConditionA:false");
                return false;
            }
    
            static bool ConditionB()
            {
                System.Console.WriteLine("ConditionB:true");
                return true;
            }

    输出:

    ConditionA:false

    short-circuit logic test end

    如你看到的那样,ConditionA()为假,那么ConditionB()就被“短路”了,根本不需要去执行。这种“只有在需要求值时才进行求值”的特点体现了“按需”的思想,可以看做是一种朴素的延迟加载。

    二、延迟加载(执行)

    在实际开发中延迟加载的思想应用非常普遍,比如图片的按需加载、某些ORM实现的查询对关联数据的加载等等。那么什么是延迟加载呢?

    百度百科解释的超级烂,但是我们都可以理解,延迟加载体现了“按需创建要使用的资源”这一核心思想。在.NET中有不少按需分配(Load On Demand)延迟加载的实现机制。下面结合实际开发试举两个常见的延迟加载的例子。

    1、yield和Linq

    yield关键字的使用记得以前总结过,可参考这一篇

    yield语句只能出现在iterator(迭代器)块中,我们可以把一些耗时的或者需要延迟的操作放在MoveNext()里面。正是yield才使Linq的延迟执行成为可能。

    在Linq中,所有实现了IEnumerable<T>接口的类都被称作sequence(序列),Linq最基本的数据单元是sequences和elements。一个sequence是实现了IEnumerable<T>的对象,而一个element是sequence中的每一个元素。如下就是一个简单的Linq查询:

        class UserInfo
        {
            public string Name { get; set; }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var lang = "python";
                var list = new List<UserInfo> {
                    new UserInfo{Name="jeffwong"},
                    new UserInfo{Name="anytao"},
                    new UserInfo{Name="dudu"}
                };
                var query = list.Where(m => m.Name.StartsWith("j"));//linq查询
                if (lang == "c#")
                {
                    foreach (var item in query)
                    {
                        Console.WriteLine(item.Name);
                    }
                }
                System.Console.Read();
            }
        }

    上面示例代码中有个if条件,就是当语言(lang)等于C#的时候输出序列中的用户(元素)的名称。但是其实这个条件为假,所以对于linq查询结果query根本没有什么作用,如果这是一个耗时的查询操作,偏偏查询结果又用不到,那不是白做了吗?好在在Linq查询实现中,query变量只是一个可迭代列表(IEnumerable<T>)对象占位符,它根本没有进行计算,也没有加载数据(这里是用户信息)进入内存,只有在foreach遍历取值的时候才会进行运算取值,显然可以节省开销。

    当然,上例中我们构造的列表数据量很小,而且本身就在内存中,就算执行了查询,好像也看不出性能上有多少提升。但是实际上在我们熟知的Linq to Sql中,IQueryable<T>就是继承实现了IEnumerable<T>接口,使用Linq To Sql访问数据库,对于网络传输和IO的影响就不得不考虑,否则很容易造成查询缓慢用户体验恶劣。好在我们可以利用Linq的延迟执行机制写出良好的查询,而且微软的Linq To Sql和ADO.NET Entity Framework框架都支持对关联数据的延迟加载机制。

    2、Lazy<T>

    .NET中典型的延迟加载按需创建对象的类就是Lazy<T>,对于那种“懒对象”的创建非常简单:

        class UserInfo
        {
            public string Name { get; set; }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Lazy<UserInfo> lazyUser = new Lazy<UserInfo>(() => new UserInfo { Name = "jeffwong" });
                if (!lazyUser.IsValueCreated) //用户还没有创建
                {
                    Console.WriteLine("User is not created yet.");
                }
                Console.WriteLine(lazyUser.Value.Name); //此时真正创建用户
                System.Console.Read();
            }
        }

    实际上Lazy<T>可以给开发者提供更多的控制选项(比如支持委托)和线程安全。

    参考:

    http://msdn.microsoft.com/en-us/library/dd642331.aspx

    http://msdn.microsoft.com/en-us/library/9k7k7cf0(v=vs.100).aspx

  • 相关阅读:
    MFC tab页面中获到其它页面的数据
    sqlite数据库中"Select * From XXX能查到数据,但是Select DISTINCT group From xxx Order By group却查不出来
    关闭程序出现崩溃(exe 已触发了一个断点及未加载ucrtbased.pdb)
    springboot 通用Mapper使用
    springBoot 发布war包
    springCloud Zuul网关
    springboot hystrix turbine 聚合监控
    springBoot Feign Hystrix Dashboard
    springBoot Ribbon Hystrix Dashboard
    springBoot Feign Hystrix
  • 原文地址:https://www.cnblogs.com/jeffwongishandsome/p/2623810.html
Copyright © 2011-2022 走看看