Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# linq方法_C#_Linq - Fatal编程技术网

C# linq方法

C# linq方法,c#,linq,C#,Linq,我在linq中搜索带有2个验证的where和2个where之间最快的方法是什么 我创建了一个虚拟测试,但它并不有效(两个测试的时间相同) 使用AutoFixture; 使用LinqList1; 使用Microsoft.VisualStudio.TestTools.UnitTesting; 使用制度; 使用System.Collections.Generic; 使用系统诊断; 使用System.Linq; 命名空间UnitTestProject1 { [测试类] 公共类UnitTest1 { [

我在linq中搜索带有2个验证的where和2个where之间最快的方法是什么

我创建了一个虚拟测试,但它并不有效(两个测试的时间相同)


使用AutoFixture;
使用LinqList1;
使用Microsoft.VisualStudio.TestTools.UnitTesting;
使用制度;
使用System.Collections.Generic;
使用系统诊断;
使用System.Linq;
命名空间UnitTestProject1
{
[测试类]
公共类UnitTest1
{
[测试方法]
公共void TestMethod1()
{
夹具=新夹具();
Print(DateTime.Now.ToLongTimeString());
List items=fixture.CreateMany(1000000.ToList();
Print(DateTime.Now.ToLongTimeString());
VarL1=项目。其中(x=>x.A)。其中(x=>x.B);
Print(DateTime.Now.ToLongTimeString());
Print(DateTime.Now.ToLongTimeString());
var l2=项目。其中(x=>x.A&&x.B);
Print(DateTime.Now.ToLongTimeString());
}
}
}

这些方法之间的差异非常小,甚至不值得考虑。下面是使用更精确的基准模板的结果。你可以看到“噪音”压倒了这些方法之间的任何实际差异

var l1 = items.Where(x => x.A).Where(x => x.B);
var l2 = items.Where(x => x.A && x.B);

var actions = new[]
{
    new TimedAction("Test 1", () =>
    {
        foreach (var element in l1) {}
    }),
    new TimedAction("Test 2", () =>
    {
        foreach (var element in l2) {}
    }),
    new TimedAction("Test 3", () =>
    {
        foreach (var element in items.Where(x => x.A).Where(x => x.B)) {}
    }),
    new TimedAction("Test 4", () =>
    {
        foreach (var element in items.Where(x => x.A && x.B)) {}
    }),
    // Add tests as desired
};

即使我们有意为第一种方法创建一个最坏情况场景(其中
a
始终为真,
B
始终为假),第一种方法也只需要多花50%的时间

如果您正在为代码中的高性能关键点(如视频游戏的渲染器)编写代码,则可能应该完全避免使用LINQ和委托。在任何其他情况下,根据可维护性和可理解性选择如何编码

使现代化 NetMage提到了伯爵,所以我。您可以看到第二种方法在使用Count时速度更快,但更重要的是,您可以看到,选择使用类似Count的方法比挑剔模式的位置提供了更大的性能增益:

    new TimedAction("Test 5", () =>
    {
        l1.Count();
    }),
    new TimedAction("Test 6", () =>
    {
        l2.Count();
    }),

DateTime.Now.ToLongTimeString()
对于性能基准没有意义,请使用
Stopwatch()
或benchmark.net。表达式的结果不会被计算。当然,这是同一时间,您所计时的只是查询的创建,而不是查询的执行。您可以使用
ToList()
来具体化查询,但我不希望这两者之间有太大的区别。这似乎是一个微观优化,因为它们在功能上是等效的,即使在您修复了上面的测试代码之后。在进行基准测试时使用benchmark dotnet如果您检查源代码,您将看到链接的
Where
方法从之前的两个lambda创建一个新的lambda,调用每个lambda并使用
&
。例如,如果
x.A
经常为
false
,则一个方法调用会慢一些。如果
x.A
通常为
true
,那么两种情况下的方法调用速度都会变慢,额外时间很少。我不确定这是否更精确,两者之间肯定会有20%的差异。我使用了
Count
而不是
foreach
,得到了45%的差异,但是
foreach
仍然显示出20%的差异。我想你可能还在测量你的线束开销。@NetMage:我的基准并不完美,但它肯定比操作代码更精确。除了实际迭代结果(OP没有这样做),它使用秒表,不涉及I/O(例如Debug.Print),并且以不同的顺序多次重复操作,以避免环境因素产生过大的影响。如果减少集合大小并增加重复次数,结果将更一致地反映您所看到的内容
Count()
是高度优化的:比foreach循环快得多,无论您使用哪个
模式;我使用
Util.ElapsedTime
并在每次试验中迭代大约30秒;尽管我也使用了LINQPad Hijack分析器,平均运行了4次,运行了6秒。但是我在测试中没有开销。我为
运行了10000个元素,将基准减少到这一点仍然没有显示出类似的差异。添加到基准以减去调用
操作时迭代的开销(初始化了int)导致基准显示了大约20%的差异。@NetMage:interest。调用一个动作给我带来的开销,但这可能是由于我没有考虑到的优化。无论如何,我觉得您的观察支持了我的主要观点:如果您处理的是性能热点,那么您根本不应该使用委托。LINQ将扼杀微观优化。但绝大多数时候,微优化都是毫无价值的:你的应用程序正在做的其他事情将远远超过一个
Where
子句与两个子句之间的差异。
var l1 = items.Where(x => x.A).Where(x => x.B);
var l2 = items.Where(x => x.A && x.B);

var actions = new[]
{
    new TimedAction("Test 1", () =>
    {
        foreach (var element in l1) {}
    }),
    new TimedAction("Test 2", () =>
    {
        foreach (var element in l2) {}
    }),
    new TimedAction("Test 3", () =>
    {
        foreach (var element in items.Where(x => x.A).Where(x => x.B)) {}
    }),
    new TimedAction("Test 4", () =>
    {
        foreach (var element in items.Where(x => x.A && x.B)) {}
    }),
    // Add tests as desired
};
    new TimedAction("Test 5", () =>
    {
        l1.Count();
    }),
    new TimedAction("Test 6", () =>
    {
        l2.Count();
    }),