2

我有一个惰性 linq 查询,它发现内存中某些 xml 中包含特定属性的元素数量。我想评估枚举该查询以获取不同长度的 xml 所需的时间长度。

为了做到这一点,我首先考虑使用对 .ToList() 的调用,因为我知道这会导致枚举所有项目。但是我认为这可能并不代表完整的评估时间,因为将有一个内存操作将所有项目从一个结构移动到另一个结构,因此切换到对 .Count() 的调用。

IEnumerable<XMLNode> nodes = "<Some Linq>"

var watch = new Stopwatch();
watch.Restart();
var test = nodes.Count();
watch.Stop();
Console.WriteLine("Enumeration Time: " + watch.ElapsedMilliseconds);

第一个问题是这是计算评估 Enumerable 所需时间的最佳方法吗?

第二个问题是哪个更能代表实际评估时间 Count() 还是 ToList()?

这是代码的一些结果,请注意在迭代之间添加了一个新的 xml 部分,这意味着每次搜索的 xml 都以相同的数量增长。

结果(来自 .Count())

Enumeration Time: 0 (ms)
Enumeration Time: 0 (ms)
Enumeration Time: 1 (ms)
Enumeration Time: 1 (ms)
Enumeration Time: 2 (ms)
Enumeration Time: 2 (ms)
Enumeration Time: 2 (ms)
Enumeration Time: 3 (ms)
Enumeration Time: 3 (ms)
Enumeration Time: 4 (ms)
Enumeration Time: 4 (ms)
Enumeration Time: 5 (ms)
Enumeration Time: 6 (ms)
Enumeration Time: 6 (ms)
Enumeration Time: 8 (ms)
Enumeration Time: 6 (ms)
Enumeration Time: 15 (ms)
Enumeration Time: 8 (ms)
Enumeration Time: 8 (ms)
Enumeration Time: 9 (ms)
Enumeration Time: 8 (ms)
Enumeration Time: 9 (ms)
Enumeration Time: 10 (ms)
Enumeration Time: 10 (ms)
Enumeration Time: 10 (ms)
Enumeration Time: 27 (ms)
Enumeration Time: 12 (ms)
Enumeration Time: 18 (ms)
Enumeration Time: 20 (ms)

结果(来自 .ToList())

Enumeration Time: 1 (ms)
Enumeration Time: 1 (ms)
Enumeration Time: 1 (ms)
Enumeration Time: 2 (ms)
Enumeration Time: 2 (ms)
Enumeration Time: 3 (ms)
Enumeration Time: 3 (ms)
Enumeration Time: 4 (ms)
Enumeration Time: 4 (ms)
Enumeration Time: 5 (ms)
Enumeration Time: 5 (ms)
Enumeration Time: 9 (ms)
Enumeration Time: 14 (ms)
Enumeration Time: 12 (ms)
Enumeration Time: 10 (ms)
Enumeration Time: 8 (ms)
Enumeration Time: 9 (ms)
Enumeration Time: 10 (ms)
Enumeration Time: 13 (ms)
Enumeration Time: 12 (ms)
Enumeration Time: 12 (ms)
Enumeration Time: 16 (ms)
Enumeration Time: 21 (ms)
Enumeration Time: 18 (ms)
Enumeration Time: 15 (ms)
Enumeration Time: 15 (ms)
Enumeration Time: 23 (ms)
Enumeration Time: 15 (ms)
Enumeration Time: 38 (ms)
4

2 回答 2

3

使用的问题var test = nodes.Count();是底层集合(如果有的话)可能正在实现IList<T>具有Count属性的集合。

作为一种优化,可以调用该属性,无论集合大小,您都将获得接近恒定的时间。

而不是ToList() Count()考虑实际迭代:

foreach(var item in nodes){}

请注意,我们没有对 - 做任何事情item- 这只会以最小的开销进行迭代。

于 2012-05-02T10:46:01.443 回答
1

你不能真正做一个有用的性能测试,比如从文件中读取。

根据文件是否在磁盘缓存中,性能会有很大差异。在您的测试中,该文件将始终在您几毫秒前访问它时被缓存,但在实时情况下它很少会被缓存,这会产生完全不同的结果。

您可以通过从 aMemoryStream而不是真实文件中读取文件数据来仅测试解析文件数据的部分。但是,读取实际文件通常会比解析它花费更长的时间,因此解析的性能通常根本不重要。

于 2012-05-02T10:54:26.257 回答