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
浙公网安备 33010602011771号