我想知道如果我将常见的 where 子句查询提取到一个常见的表达式中,它是否会使我的查询更快,如果我在一个集合上说了 10 个 linq 查询,其中 where 子句的第一部分完全相同。
我做了一个小例子来说明更多。
public class Person
{
public string First { get; set; }
public string Last { get; set; }
public int Age { get; set; }
public String Born { get; set; }
public string Living { get; set; }
}
public sealed class PersonDetails : List<Person>
{
}
PersonDetails d = new PersonDetails();
d.Add(new Person() {Age = 29, Born = "Timbuk Tu", First = "Joe", Last = "Bloggs", Living = "London"});
d.Add(new Person() { Age = 29, Born = "Timbuk Tu", First = "Foo", Last = "Bar", Living = "NewYork" });
Expression<Func<Person, bool>> exp = (a) => a.Age == 29;
Func<Person, bool> commonQuery = exp.Compile();
var lx = from y in d where commonQuery.Invoke(y) && y.Living == "London" select y;
var bx = from y in d where y.Age == 29 && y.Living == "NewYork" select y;
Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}", lx.Single().Age, lx.Single().First , lx.Single().Last, lx.Single().Living, lx.Single().Born );
Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}", bx.Single().Age, bx.Single().First, bx.Single().Last, bx.Single().Living, bx.Single().Born);
那么这里的一些大师能否给我一些建议,如果写这样的查询是一个好习惯
var lx = "Linq Expression "
或
var bx = "Linq Expression" ?
如有任何意见,我们将不胜感激。
谢谢, 股份公司
最佳答案
首先,Eric 完全正确:如果您关心性能,则需要对其进行衡量。准确计算出您要测量的内容,并记录您在代码中所做的每次更改所发生的情况。基准测试的各个方面我现在没有时间深入探讨,但关键可能是确保您运行测试的时间足够长以使其有意义——如果您的测试只需要 50 毫秒,那么您不太可能从噪音中分辨出代码的改进。
现在,如果您正在使用 LINQ to Objects,那么您几乎肯定根本不想使用表达式树。坚持委托(delegate) - 这就是 LINQ to Objects 所使用的方式。
现在,至于重组...如果您有一个共同的谓词,那么您可以通过它来过滤您的列表,以得出一个新的 IEnumerable<T>
。 .谓词将延迟应用,因此它不会对执行速度产生任何影响,但它可能使您的代码更具可读性。它可能会非常轻微地减慢速度,因为当您有效地获得两个不同的 where
时,它会引入额外的间接级别。条款。
如果应用过滤器的结果只有很少的结果,您可能想要具体化它(例如通过调用 ToList
)并记住结果 - 这样您就不需要为第二个查询再次查询整个事情。
但是,我能看到的大好处是只调用 Single
每个查询一次。目前,您正在为每个属性执行整个查询 - 这显然效率低下。
这是你的代码,相应地重写了——并且也使用了一个集合初始值设定项:
PersonDetails d = new PersonDetails
{
new Person {Age = 29, Born = "Timbuk Tu", First = "Joe",
Last = "Bloggs", Living = "London"},
new Person { Age = 29, Born = "Timbuk Tu", First = "Foo",
Last = "Bar", Living = "NewYork" }
};
var peopleOfCorrectAge = d.Where(a => a.Age == 29);
var londoners = peopleOfCorrectAge.Where(p => p.Living == "London");
var newYorkers = peopleOfCorrectAge.Where(p => p.Living == "New York");
var londoner = londoners.Single();
var newYorker = newYorker.Single();
Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}",
londoner.Age, londoner.First,
londoner.Last, londoner.Living, londoner.Born);
Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}",
newYorker.Age, newYorker.First,
newYorker.Last, newYorker.Living, newYorker.Born);
或者,对于最后一节,封装“写出一个人”:
DisplayPerson(londoners.Single());
DisplayPerson(newYorkers.Single());
...
private static void DisplayPerson(Person person)
{
Console.WriteLine("All Details {0}, {1}, {2}, {3}, {4}",
person.Age, person.First,
person.Last, person.Living, person.Born);
}
关于c# - Linq 查询性能,比较编译查询与非编译查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2494475/