Linq 中的streaming 和 non-streaming

  

流式

流式运算符不需要在生成元素前读取所有源数据。在执行时,流式运算符一边读取每个源元素,一边对该源元素执行运算,并在可行时生成元素。流式运算符将持续读取源元素直到可以生成结果元素。这意味着可能要读取多个源元素才能生成一个结果元素。

非流式

非流式运算符必须读取所有源数据才能生成结果元素。诸如排序和分组等运算属于此类别。在执行时,非流式查询运算符读取所有源数据,将其放入数据结构中,执行运算,然后生成结果元素。

 

以上的定义来自msdn,作为延时运行的两个类型而言,刚接触时觉得似乎不是太有必要,都是yield,弄这么麻烦干嘛。

了解后,略有体会,记录于此。

1.时间和内存   这是程序猿们最关心的两个问题

  streaming 每次加载一个元素,但消耗的时间会多;

  non-streaming 会把所以元素加载到内存中,内存消耗较大,但总体时间较快。

  这两个可以以从数据库中读取数据为例,简单想象一下就知道了,不具体写代码分析了

  P.S. 这里不考虑性能的瓶颈

2.枚举无限(infinite)元素

  这样的场景还是较为常见的,如果数据源的数据源源不断的进来,或者是一个循环的队列,都可以认为是一个无限的集合

  例如: 

public IEnumerable<int> GetNumbers(int start)
{
    int num = start;

    while(true)
    {
        yield return num;
        num++;
    }
}

  运行时:

foreach (var num in GetNumbers(0).Where(x => x % 2 == 0))
{
    Console.WriteLine(num);
}

如果使用Orderby这样的non-streaming,会outofmemory

3.还有一类,两者都是的 

  像GroupJoin,Join 既是streaming又是non-streaming的,用Reflector 看了一下,大约是指在计算数据的时候是非流式的,在返回数据的时候是流式的

  不过感觉还是不对,希望有了解的小伙伴能详细解释一下

 

引用:

http://msdn.microsoft.com/zh-cn/library/bb882641(v=vs.120).aspx;

http://stackoverflow.com/questions/10036033/how-does-a-streaming-operator-differ-from-deferred-execution

  

 

posted on 2014-04-22 17:13  胖师傅  阅读(474)  评论(0)    收藏  举报

导航