【发布时间】:2018-07-01 11:55:56
【问题描述】:
我对这里的结果有点困惑,也许有人可以给我一些见解?
基本上,我正在尝试测试使用之间的性能
OfType(x)Where(_ = _ is x).Select((X)x)Where(_ = _.Type = type).Select((X)x)
以下是课程:
public enum AnimalTypes { Alligator, Bear, Cat, Dog, Elephant }
public interface IAnimal
{
AnimalTypes Type { get; }
}
public class Bear : IAnimal
{
public AnimalTypes Type => AnimalTypes.Bear;
}
public class Cat : IAnimal
{
public AnimalTypes Type => AnimalTypes.Cat;
}
编辑:此代码是基于 cmets 修复的!抱歉错误 这是测试方法
void Main()
{
List<IAnimal> animals = new List<IAnimal>();
for (int i = 0; i < 100000; i++)
{
animals.Add(new Bear());
animals.Add(new Cat());
}
// tests
IEnumerable<Cat> test1 = animals.OfType<Cat>();
IEnumerable<Cat> test2 = animals.Where(_ => _ is Cat).Select(_ => (Cat)_);
IEnumerable<Cat> test3 = animals.Where(_ => _.Type == AnimalTypes.Cat).Select(_ => (Cat)_);
Stopwatch sw = new Stopwatch();
// OfType
sw.Start();
test1.ToArray();
sw.Stop();
Console.WriteLine($"OfType = {sw.ElapsedTicks} ticks");
sw.Reset();
// Where (is) + Select
sw.Start();
test2.ToArray();
sw.Stop();
Console.WriteLine($"Where (is) + Select = {sw.ElapsedTicks} ticks");
sw.Reset();
// Where (enum) + Select
sw.Start();
test3.ToArray();
sw.Stop();
Console.WriteLine($"Where (type) + Select = {sw.ElapsedTicks} ticks");
sw.Reset();
}
奇怪的是,结果总是确保最后一次测试得到最好的结果......
【问题讨论】:
-
Emh...您只是在创建查询,而不是实际执行它们。在每个查询的末尾添加
.ToArray() -
请注意
type == type是精确的类型比较,而is/OfType支持子类(例如 Siamese 是 Cat,OfType() 和 is Cat 都会返回暹罗猫) -
这段代码实际上是在测量 jitting 开销,第一个总是很昂贵。始终重复测试至少 10 次,您会看到这种开销消失了。感受一下数字,2 滴答声太快了。否则通过将集合大小加倍很容易看到。谷歌“linq 延迟执行”以了解更多信息。一旦你修复它,当心像这样非常快速的代码的嘈杂结果,你应该看到类型比较是最快的。应该是,不需要像 is 和 OfType 那样检查类型层次需要做的。
-
谢谢大家,我更新了我的代码,但仍然得到不寻常的结果。
-
不确定否决票。请告诉我如何改进问题?
标签: c#