Enumerable.Range与for循环

时间:2016-10-19 11:11:27

标签: c# .net performance for-loop enumerable

我想知道使用Enumerable.Range对使用foreach循环的性能开销是多少。例如:

var stringArray = Enumerable.Range(0, 4).Select(i => string.Empty).ToArray();

VS

var stringArray = new string[4];
for (int i = 0; i < formatted.Length; i++)
{
    stringArray[i] = string.Empty;
}

我发现了这些问题:

  1. Why is Enumerable.Range faster than a direct yield loop?

  2. Enumerable.Range implementation

  3. Thoughts on foreach with Enumerable.Range vs traditional for loop

  4. 但是我最后担心Select然后我可能会循环两次。但是我喜欢使用Range选项的优雅。

2 个答案:

答案 0 :(得分:4)

从下面的测试中,for效率更高:(以毫秒为单位,差异为-3毫秒 - 这是无关紧要的......)

var watch = System.Diagnostics.Stopwatch.StartNew();
var stringArra1y = Enumerable.Range(0, 4).Select(i => string.Empty).ToArray();
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //3305

watch = System.Diagnostics.Stopwatch.StartNew();
var stringArray2 = new string[4];
for (int i = 0; i < stringArray2.Length; i++)
{
    stringArray2[i] = string.Empty;
}
watch.Stop();
Console.WriteLine(watch.ElapsedTicks); //1

但您可以使用Enumerable.Range().Select而不是.Repeat使用var watch = System.Diagnostics.Stopwatch.StartNew(); var stringArra1y = Enumerable.Repeat(string.Empty, 4).ToArray(); watch.Stop(); Console.WriteLine(watch.ElapsedTicks); //391

.ToArray()

在说完上面的通知后,你在这里谈论非常小的收藏品(4项)。在较大的集合中,尤其是如果删除var watch = System.Diagnostics.Stopwatch.StartNew(); var stringArra1y = Enumerable.Repeat(string.Empty, 100000); watch.Stop(); Console.WriteLine(watch.ElapsedTicks); //360 watch = System.Diagnostics.Stopwatch.StartNew(); var stringArray2 = new string[100000]; for (int i = 0; i < stringArray2.Length; i++) { stringArray2[i] = string.Empty; } watch.Stop(); Console.WriteLine(watch.ElapsedTicks); //1335 ,它的行为不相同:

.Range

  

但是我担心最后选择Select,实际上我可能会循环两次

尽管Repeatyield return的{​​{3}}都是通过static IEnumerable<int> RangeIterator(int start, int count) { for (int i = 0; i < count; i++) yield return start + i; } 来实现的:

.Select

所以它也被id执行了,就像Stopwatch意味着它不会循环两次。

并非使用for每次运行会返回不同的结果,但整体构思如上所示

IMO ,特别是在小型集合的情况下,为了提高可读性而进行了较小的性能改进。当你遇到性能问题时,只有在获得更大的鱼(例如List<>上的嵌套HashSet<>循环而不是使用/var/www)之后,才能处理这样的事情。

答案 1 :(得分:1)

在我非常简单的测试中,看起来对于1 000 000个字符串,循环速度提高了38ms。

static void Main(string[] args)
        {
            var start = DateTime.Now;
            EnTest();
            var end = DateTime.Now;

            var firstResult = end - start;
            Console.WriteLine("Difference for Enumerable: {0}ms", firstResult.Milliseconds);

            GC.Collect();
            Thread.Sleep(2000);

            var secondStart = DateTime.Now;
            ArTest();
            var secondEnd = DateTime.Now;

            var secondResult = secondEnd - secondStart;
            Console.WriteLine("Difference for loop: {0}ms", secondResult.Milliseconds);

            var globalResult = firstResult - secondResult;
            Console.WriteLine("Difference between tests: {0}ms", globalResult.Milliseconds);

            Console.ReadKey();
        }

        public static void EnTest()
        {
            var stringArray = Enumerable.Range(0, 1000000).Select(i => string.Empty).ToArray();
        }

        public static void ArTest()
        {
            var stringArray = new string[1000000];
            for (int i = 0; i < stringArray.Length; i++)
            {
                stringArray[i] = string.Empty;
            }
        }