gpt4 book ai didi

c# - 完整性检查 : Do these nested . 所有调用都等同于 LINQ 中相应的 .Where 和 .SelectMany 调用?

转载 作者:太空宇宙 更新时间:2023-11-03 21:06:23 28 4
gpt4 key购买 nike

我有以下代码:

bool b = myList
.All(x => x.MyList
.Where(y => y.MyBool)
.All(y => y.MyList
.All(z => z.MyBool)))

这在功能上等同于:

bool b = myList
.SelectMany(x => x.MyList)
.Where(x => x.MyBool)
.SelectMany(x => x.MyList)
.All(x => x.MyBool)

我认为是的,但我的同事向我提出质疑,这种变化可能在某些情况下在功能上有所不同(例如,如果任何集合为空)。

尽管答案要么是,要么不是,但对于在可读性、圈复杂度、时间复杂度和性能方面哪一个更好的任何意见,我们也将不胜感激。

更新:

因此,我使用以下代码分析了代码:

static void Main(string[] args)
{
var myList = new List<A>();

for (var j = 0; j < 1000; j++)
{
var a = new A();

for (var k = 0; k < 1000; k++)
{
var b = new B {MyBool = true};

for (var l = 0; l < 1000; l++)
{
var c = new C {MyBool = true};
b.MyList.Add(c);
}

a.MyList.Add(b);
}

myList.Add(a);
}

for (var x = 0; x < 10000; x++)
{
bool b1 = Foo(myList);
}

for (var x = 0; x < 10000; x++)
{
bool b2 = Bar(myList);
}
}

private static bool Foo(List<A> myList)
{
return myList
.All(x => x.MyList
.Where(y => y.MyBool)
.All(y => y.MyList
.All(z => z.MyBool)));
}

private static bool Bar(List<A> myList)
{
return myList
.SelectMany(x => x.MyList)
.Where(x => x.MyBool)
.SelectMany(x => x.MyList)
.All(x => x.MyBool);
}

private class A
{
public List<B> MyList => new List<B>();
}

private class B
{
public bool MyBool { get; set; }

public List<C> MyList => new List<C>();
}

private class C
{
public bool MyBool { get; set; }
}

我发现第二种方法 (Bar) 使用 .SelectMany.Where 比第一种方法快将近 80% (Foo) 使用嵌套的 .All 调用。但这只能在非常大的数据集上证明,实际花费的时间非常少。如果每个元素调用一个需要较长时间的查询(例如,对数据库),如果性能差异确实是由于元素被读取的次数引起的,那么这在较小的数据集上可能更重要。但是,如果差异是由于读取元素之间的开销造成的,并且两种方法读取元素的次数相同,那么我想无论数据集大小或元素读取时间如何,性能差异总是可以忽略不计。

以下结果(来自 Visual Studio Performance Profiler): enter image description here

最佳答案

myList.All // is it true for all elements in myList that…
(x => x.MyList //in their MyList property
.Where(y => y.MyBool) // those elements that have MyBool returning true
.All( // have it true for all elements in that list that…
y => y.MyList //in their MyList property
.All(z => z.MyBool) // all elements have MyBool returning true


myList.SelectMany( // for all the elements in myList
x => x.MyList) // for all elements in their MyList property…
.Where(x => x.MyBool) // that have MyBool returning true
.SelectMany( // for all those elements
x => x.MyList) // for all elements in their MyList property
.All(x => x.MyBool) // is it true that all elements have MyBool returning true

所以是的,它们具有相同的含义。特别是对于任何一种情况,任何阶段的空列表都意味着 All() 方法中的 true,无论 true 来自空虚是否传递给调用 All() 或传递给最终 All() 的空值。

可读性是一个更主观的问题,因为所提出的问题涉及几个如果-这个-那么-那个的步骤,这本质上是繁琐的,因此会导致繁琐的表达。我赞成第一种,但不是太过分或教条化。

时间复杂度是一样的。性能可能会很大。乍一看,第二个的内部结构似乎更多地链接了枚举器,这可能会使它稍微慢一些,但我不会在这上面打赌很多钱;如果我非常关心这里的性能,我肯定会介绍两者。

关于c# - 完整性检查 : Do these nested . 所有调用都等同于 LINQ 中相应的 .Where 和 .SelectMany 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40886535/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com