难道LINQ缓存运算值? [英] Does LINQ cache computed values?

查看:106
本文介绍了难道LINQ缓存运算值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下的code:

Suppose I have the following code:

var X = XElement.Parse (@"
    <ROOT>
        <MUL v='2' />
        <MUL v='3' />
    </ROOT>
");
Enumerable.Range (1, 100)
    .Select (s => X.Elements ()
        .Select (t => Int32.Parse (t.Attribute ("v").Value))
        .Aggregate (s, (t, u) => t * u)
    )
    .ToList ()
    .ForEach (s => Console.WriteLine (s));

什么是.NET运行时居然在这里做什么?它是解析和转换属性为整数各100次,或者是足够聪明弄清楚,它应该缓存解析值,而不是重复计算的范围内的每个元素?

What is the .NET runtime actually doing here? Is it parsing and converting the attributes to integers each of the 100 times, or is it smart enough to figure out that it should cache the parsed values and not repeat the computation for each element in the range?

此外,我怎么会去找出这样的事情我自己?

Moreover, how would I go about figuring out something like this myself?

在此先感谢您的帮助。

推荐答案

这已经有一段时间,因为我挖通过这个code,但IIRC,顺便选择工作原理是简单地缓存 Func键您提供它和源收集一次运行它。因此,在外部范围中的每个元素,它将运行内部选择/聚合序列,就好像它是第一次。没有任何内置缓存事情 - 你就必须执行该在自己的前$ ​​P $ pssions

It has been a while since I dug through this code but, IIRC, the way Select works is to simply cache the Func you supply it and run it on the source collection one at a time. So, for each element in the outer range, it will run the inner Select/Aggregate sequence as if it were the first time. There isn't any built-in caching going on -- you would have to implement that yourself in the expressions.

如果你想算出这个你自己,你有三个基本选项:

If you wanted to figure this out yourself, you've got three basic options:

  1. 编译code,并使用反汇编查看IL;这是最准确的,但是,特别是lambda表达式和闭包,你从IL获得可能看起来一点也不像你所投入的C#编译器。
  2. 使用类似dotPeek反编译System.Linq.dll到C#;再次,你得到了这些工具的东西可能只有大约类似于原始出处code,但至少这将是C#(尤其是和dotPeek做了pretty的好工作,而且是免费的。)
  3. 在我个人的preference - 下载.NET 4.0 参考源并寻找自己;这就是它的:)你必须只相信MS的参考源用来产生二进制文件的实际源相匹配,但我看不出有什么充分的理由怀疑它们。
  4. 正如刚才@AllonGuralnek您可以设置在一个特定的行前的lambda pressions断点;将光标置于某处的Lambda和preSS F9的体内,它会断点只是拉姆达。 (如果你这样做是错误的,它会突出显示断点颜色整行;如果你这样做是正确的,它只会凸显拉姆达)
  1. Compile the code and use ildasm to view the IL; it's the most accurate but, especially with lambdas and closures, what you get from IL may look nothing like what you put into the C# compiler.
  2. Use something like dotPeek to decompile System.Linq.dll into C#; again, what you get out of these kinds of tools may only approximately resemble the original source code, but at least it will be C# (and dotPeek in particular does a pretty good job, and is free.)
  3. My personal preference - download the .NET 4.0 Reference Source and look for yourself; this is what it's for :) You have to just trust MS that the reference source matches the actual source used to produce the binaries, but I don't see any good reason to doubt them.
  4. As pointed out by @AllonGuralnek you can set breakpoints on specific lambda expressions within a single line; put your cursor somewhere inside the body of the lambda and press F9 and it will breakpoint just the lambda. (If you do it wrong, it will highlight the entire line in the breakpoint color; if you do it right, it will just highlight the lambda.)

这篇关于难道LINQ缓存运算值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆