【问题标题】:Why property "ElapsedTicks" of List not equal to "ElapsedTicks" of Array?为什么 List 的属性“ElapsedTicks”不等于 Array 的“ElapsedTicks”?
【发布时间】:2015-07-06 01:55:22
【问题描述】:

例如我有以下代码实现秒表:

var list = new List<int>();
var array = new ArrayList();

Stopwatch listStopwatch = new Stopwatch(), arrayStopwatch = new Stopwatch();

listStopwatch.Start();
for (int i =0; i <=10000;i++)
{
    list.Add(10);
}

listStopwatch.Stop();

arrayStopwatch.Start();
for (int i = 0; i <= 10000; i++)
{
    list.Add(10);
}
arrayStopwatch.Stop();

Console.WriteLine(listStopwatch.ElapsedTicks > arrayStopwatch.ElapsedTicks);

为什么这个值不相等?

【问题讨论】:

  • 为什么它们应该是一样的?
  • 不保证相同。他们可能会,也可能不会。如果您有一个论点是它们必须相等,请先告诉我们您的论点。
  • 一个更有趣的问题是问为什么一个比另一个快。
  • 第二个循环应该是array吗?
  • 顺便说一句,ArrayList 不是数组(int[])。

标签: c# .net stopwatch


【解决方案1】:

不同的代码预计会产生不同的时序。

第二个循环作为问题暗示添加到数组中

一个最明显的区别是 ArrayList 中的装箱 - 每个 int 都存储为装箱值(在堆上创建而不是 List&lt;int&gt; 的内联)。

第二个循环添加到list,如示例所示

增长的列表需要重新分配和复制所有元素,如果在特定范围内它会遇到更多的重新分配,第二组元素可能会更慢(因为复制操作每次都需要复制更多的元素)。

请注意,平均而言(正如 Adam Houldsworth 所暗示的)重新分配的成本是相同的(因为当数组增长时它们发生的频率最低),但是当有额外的重新分配时,人们可以找到一组数字使一个数字始终不同于另一个数字。为了使差异保持一致,需要添加更多数量的项目。

【讨论】:

  • 在这种情况下,它可能只复制一份。 list 的复制算法是一个加倍动作。第一个循环将进行多次调整大小,直到您超过 10000 个项目,第二个循环保证进行零个或一个调整大小(因为第一个循环将其放置至少 10000 个或更多项目),但它会很大.
  • 它帮助我理解了!非常感谢!!
猜你喜欢
  • 2011-03-01
  • 2012-02-12
  • 1970-01-01
  • 2019-04-16
  • 2012-02-15
  • 2019-02-23
  • 2017-12-24
  • 2013-05-15
  • 1970-01-01
相关资源
最近更新 更多