[英]Linq Query Performance , comparing Compiled query vs Non-Compiled
我想知道我是否将公共where子句查询提取到一个公共表达式中,如果我说过对带有where子句的第一部分完全相同的集合的10个linq查询,它会使我的查询更快。
我做了一个小例子来解释更多。
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" ?
任何输入将不胜感激。
谢谢,AG
首先,埃里克(Eric)绝对正确:如果您担心性能,则需要对其进行评估 。 精确计算出要测量的内容,并记录您在代码中进行的每个更改所发生的情况。 我现在没有时间进行基准测试的各个方面,但是关键之一可能是确保测试运行足够长的时间,以使它们有意义-如果测试仅花费50毫秒,不可能从噪音中分辨出代码的改进。
现在,如果您正在使用LINQ to Objects,那么几乎可以肯定根本就不想使用表达式树。 坚持委托-无论如何,这就是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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.