C# LINQ 优化

发布于 2024-10-30 14:50:04 字数 433 浏览 0 评论 0原文

优化以下类型的语句的正确方法是什么:

IEnumerable<T> sequence = BuildSequence();
// 'BuildSequence' makes some tough actions and uses 'yield return'
// to form the resulting sequence.

现在,如果我愿意只采用一些第一个元素,我可以使用类似的东西:

sequence.Take(5);

所以,如果我的序列来自 BuildSequence 实际上包含数千个元素,我显然不希望构建所有元素,因为我只需要其中 5 个。

LINQ 是否可以优化此类操作,还是我必须自己发明一些东西?

What would be the proper way of optimizing the following kind of statements:

IEnumerable<T> sequence = BuildSequence();
// 'BuildSequence' makes some tough actions and uses 'yield return'
// to form the resulting sequence.

Now, if I'm willing to take only some of the first elements, I could use something like:

sequence.Take(5);

And so, if my sequence from BuildSequence actually contains several thousands of elements, I obviously don't want all of them to be constructed, because I would only need 5 of them.

Does LINQ optimize this kind of operations or I would have to invent something myself?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

明媚如初 2024-11-06 14:50:04

迭代器块yield return)为您处理这个问题;迭代器块是一个 API;工作仅在迭代器(或 Dispose())上的每次 MoveNext() 调用期间发生。由于 Take() also 不会读取整个流,因此保留了此行为。

但请注意,某些操作需要在本地缓冲数据 - 尤其是 GroupByOrderBy;但只要您使用非缓冲操作,就可以了。

例如:

static IEnumerable<int> ReadInts() {
    var rand = new Random();
    while(true) yield return rand.Next();
}
...
int count = ReadInts().Take(10).Count(); // 10 - it doesn't loop forever

The iterator block (yield return) handles this for you; an iterator block is a streaming API; work only happens during each MoveNext() call on the iterator (or on Dispose()). Because Take() also doesn't read the entire stream, this behaviour is preserved.

Note, however, that some operations need to buffer the data locally - GroupBy and OrderBy most notably; but as long as you use non-buffering operations, you are fine.

For example:

static IEnumerable<int> ReadInts() {
    var rand = new Random();
    while(true) yield return rand.Next();
}
...
int count = ReadInts().Take(10).Count(); // 10 - it doesn't loop forever
请止步禁区 2024-11-06 14:50:04

您应该看一下:

LINQ 和 Deferred执行

You should take a look on this:

LINQ and Deferred Execution

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文