为什么 AddRange 比使用 foreach 循环更快? [英] Why is AddRange faster than using a foreach loop?

查看:43
本文介绍了为什么 AddRange 比使用 foreach 循环更快?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

var fillData = new List<int>();
for (var i = 0; i < 100000; i++)
     fillData.Add(i);

var stopwatch1 = new Stopwatch();
stopwatch1.Start();

var autoFill = new List<int>();
autoFill.AddRange(fillData);
stopwatch1.Stop();

var stopwatch2 = new Stopwatch();
stopwatch2.Start();

var manualFill = new List<int>();

foreach (var i in fillData)
    manualFill.Add(i);
stopwatch2.Stop();

当我从 stopwach1stopwach2 获取 4 个结果时,stopwatch1 的值总是低于 秒表2.这意味着 addrange 总是比 foreach 快.有谁知道为什么?

When I take 4 results from stopwach1 and stopwach2, stopwatch1 has always lower value than stopwatch2. That means addrange is always faster than foreach. Does anyone know why?

推荐答案

潜在地,AddRange 可以检查传递给它的值在哪里实现 IListIList<;.如果是,它可以找出范围内有多少个值,因此需要分配多少空间……而 foreach 循环可能需要重新分配几次.

Potentially, AddRange can check where the value passed to it implements IList or IList<T>. If it does, it can find out how many values are in the range, and thus how much space it needs to allocate... whereas the foreach loop may need to reallocate several times.

另外,即使在分配之后,List 也可以使用IList.CopyTo 执行到底层数组的批量复制(当然,对于实现 IList 的范围.)

Additionally, even after allocation, List<T> can use IList<T>.CopyTo to perform a bulk copy into the underlying array (for ranges which implement IList<T>, of course.)

我怀疑你会发现,如果你再次尝试你的测试,但使用 Enumerable.Range(0, 100000) 作为 fillData 而不是 List<;T>,两者的时间差不多.

I suspect you'll find that if you try your test again but using Enumerable.Range(0, 100000) for fillData instead of a List<T>, the two will take about the same time.

这篇关于为什么 AddRange 比使用 foreach 循环更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆