相关疑难解决方法(0)

C#Lambda性能问题/可能性/指南

我正在使用各种lambda表达式语法测试性能差异.如果我有一个简单的方法:

public IEnumerable<Item> GetItems(int point)
{
    return this.items.Where(i => i.IsApplicableFor(point));
}
Run Code Online (Sandbox Code Playgroud)

然后这里有一些与point参数相关的变量提升,因为它是lambda视角的自由变量.如果我将这种方法称为百万次,那么保持原样或以任何方式改变它以改善其性能会更好吗?

我有哪些选择,哪些选项实际可行?据我所知,我必须摆脱自由变量,因此编译器不必创建闭包类并在每次调用此方法时实例化它.与非闭合版本相比,此实例化通常需要大量时间.

问题是我想提出一些通常会起作用的lambda写作指南,因为看起来每次我写一个受到重创的lambda表达式时我都会浪费一些时间.我必须手动测试它以确保它能够工作,因为我不知道要遵循什么规则.

替代方法

&示例控制台应用程序代码

我还写了一个不同版本的同一个方法,不需要任何变量提升(至少我认为它没有,但你了解这个让我知道是否是这种情况):

public IEnumerable<Item> GetItems(int point)
{
    Func<int, Func<Item, bool>> buildPredicate = p => i => i.IsApplicableFor(p);
    return this.items.Where(buildPredicate(point));
}
Run Code Online (Sandbox Code Playgroud)

在这里查看Gist.只需创建一个控制台应用程序并将整个代码复制到块Program.cs内的文件中namespace.您将看到第二个示例即使不使用自由变量也要慢得多.

一个矛盾的例子

我想构建一些lambda最佳使用指南的原因是我之前遇到过这个问题,令我惊讶的是,当使用谓词构建器 lambda表达式时,结果更快.

现在解释一下.我完全迷失在这里,因为当我知道我的代码中有一些繁重的使用方法时,我可能根本不会使用lambdas.但我想避免这种情况,并深究这一切.

编辑

你的建议似乎不起作用

我已经尝试实现一个自定义查找类,其内部工作方式与编译器使用自由变量lambda类似.但是,我没有使用闭包类,而是实现了模拟类似场景的实例成员.这是代码:

private int Point { get; set; }
private bool IsItemValid(Item item)
{
    return item.IsApplicableFor(this.Point);
}

public IEnumerable<TItem> GetItems(int point)
{ …
Run Code Online (Sandbox Code Playgroud)

c# lambda performance-testing lifting

28
推荐指数
1
解决办法
2635
查看次数

FirstOrDefault的性能()

查看我今天使用性能分析器处理的webapp的一部分.我认为联盟正在造成一些延误,但却找到了其他令人惊讶的结果.

减速的原因之一似乎是FirstOrDefault.

这是一个非常简单的LINQ查询,如下所示:

foreach(Report r in reports)
    IDTOStudy study = studies.FirstOrDefault(s => s.StudyID == r.StudyID);
Run Code Online (Sandbox Code Playgroud)

我创建了一个小方法来复制我认为FirstOrDefault正在做的行为.

private IDTOStudy GetMatchingStudy(Report report, IList<IDTOStudy> studies)
{
    foreach (var study in studies)
    if (study.StudyID == report.StudyID)
        return study;

    return null;
}
Run Code Online (Sandbox Code Playgroud)

此方法将FirstOrDefault替换为如下所示:

foreach(Report r in reports)
    IDTOStudy study = GetMatchingStudy(r, studies);
Run Code Online (Sandbox Code Playgroud)

查看使用性能分析器运行的新代码显示FirstOrDefault需要两倍的时间来完成我的新方法.这令人震惊.

我必须做一些不正确的FirstOrDefault()查询.它是什么?

FirstOrDefault()完成整个查询然后采取第一个元素?

我怎样才能加快速度并使用FirstOrDefault()

编辑1:

我注意到的另一点是,分析器说我在这两个实现上都在最大化CPU.这也是我不关心的事情,也没想到.我添加的额外方法没有减少尖峰,只是将其持续时间缩短了一半.

编辑3:

将研究纳入字典大大改善了运行时间.这肯定是承诺代码的外观.但是不回答关于FirstOrDefault的问题.

编辑2:

这是一个简单的控制台应用程序中请求的示例代码.我的运行仍然表明,在大多数情况下,FirstOrDefault需要更长时间.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reactive.Linq;
using System.Reactive.Concurrency;
using System.Diagnostics;

namespace …
Run Code Online (Sandbox Code Playgroud)

.net c# linq

6
推荐指数
1
解决办法
6380
查看次数

标签 统计

c# ×2

.net ×1

lambda ×1

lifting ×1

linq ×1

performance-testing ×1