首先,埃里克是绝对正确的:如果你关心性能,你需要
测量它
. 准确地计算出您想要测量的内容,并记录您在代码中所做的每一个更改所发生的情况。基准测试有很多方面,我现在没有时间讨论,但关键的一点可能是要确保测试运行的时间足够长,使它们有意义——如果测试只需要50毫秒,那么您不太可能从噪音中分辨出代码的改进。
现在,如果您使用的是linq-to对象,那么您几乎肯定不想使用表达式树。坚持委托-这就是LinqToObjects使用的方法。
现在,关于重组……如果你有一个共同的谓词,那么你可以用它过滤你的列表,从中开始,想出一个新的谓词。
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);
}