C# for 和 foreach 性能测试

for与foreach从性能上来讲几乎是一样的,主要区别在栈内存的使用上。foreach会涉及迭代器,而迭代器会使用栈内存。从某种程度来说,foreach其实是一种语法糖,甚至连微软也推荐在循环中操作集合涉及到添加或移除项时只使用for,否则可能会产生不可预知的副作用。

测试方式是for 和 foreach 分别遍历一个数组一百万次。

测试1:遍历数组时,每个元素只访问一次

测试2:遍历数组时,每个元素访问多次

测试环境

1. macOS
2. Mono Runtime

Program.cs

using System;
using System.Diagnostics;

class Program {
    static void Main() {
        Console.WriteLine ("Runing Csharp Loop Performace Test.");
        const int loop_count = 1000 * 1000 * 100;
        int[] array = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
        // 测试 for 性能
        var watch_1 = Stopwatch.StartNew();
        for (int i = 0; i < loop_count; i++) {
            TestCase.case_for(array);
        }
        watch_1.Stop();
        // 测试 foreach 性能
        var watch_2 = Stopwatch.StartNew();
        for (int i = 0; i < loop_count; i++) {
            TestCase.case_foreach(array);
        }
        watch_2.Stop();

        Console.WriteLine ("case for: " +
                           ((double)(watch_1.Elapsed.TotalMilliseconds * 1000000) / loop_count).ToString("0.0 ns"));
        Console.WriteLine ("case foreach: " +
                           ((double)(watch_2.Elapsed.TotalMilliseconds * 1000000) / loop_count).ToString("0.0 ns"));
    }
}

测试1[for 测试]

class TestCase {
    public static int case_for(int[] array) {
        int result = 0;
        for (int i = 0; i < array.Length; i++) {
            result += array[i];
        }
        return result;
    }
}

测试1 [foreach 测试]

class TestCase {
    public static int case_foreach(int[] array) {
        int result = 0;
        foreach (int value in array) {
            result += value;
        }
        return result;
    }
}

测试1耗时

Runing Csharp Loop Performace Test.
case for: 12.1 ns
case foreach: 12.6 ns

测试2 [for 测试]

class TestCase {
    public static int case_foreach(int[] array) {
        int result = 0;
        foreach (int value in array) {
            result += value;
            result += value;
            result += value;
        }
        return result;
    }
}

测试2 耗时

uning Csharp Loop Performace Test.
case for: 20.5 ns
case foreach: 15.4 ns

结论

for的性能是要比foreach要高出一些,但测试1和测试2对比。 需要频繁去访问集合中的元素

result += array[i];

反而会比用foreach还要慢,因为foreach已经把元素取出后无需再次访问集合,元素已经在栈内存中。

所以在使用循环时,也需要考虑实际场景。如果循环内只会访问一次元素,则用for,如果访问多次元素则用foreach,但从易用性以及风格统一的考虑推荐使用foreach,除非有特殊需求再考虑使用for循环。