先说测试结果:
for比foreach快,for循环不额外定义length似乎更快
(有网友评论说我的结论有些问题。foreach和for的效率是一样的。
感谢评论,我觉得有道理,于是我在循环内加了运行代码,重新测了一下,结果没变,但是发现点新东西)

Mono在.net 3.5运行环境下,似乎有bug会导致foreach的效率出问题。foreach比for慢。
当Mono升级到.net 4.0运行环境后,foreach效率的BUG消失了,foreach比for快。

参考资料:
《作为Unity3D的脚本而言,c#中for是否真的比foreach效率更高?》
https://www.zhihu.com/questio...

所以结论更正如下:
1.mono在.net 3.5运行环境下,有bug会导致foreach效率比for慢。
2.mono在.net 4.0运行环境下,该bug修复,以下测试结果表明foreach比for快。
3.对于数组,在外部定义一个length循环比直接使用array.length的效率更低,是负优化。

其他结论:
1.由于for和foreach效率差别较小,如果不是特别严格要求性能的情况下,喜欢哪种写法用哪种。如果特别严格要求性能的时候,请具体比较测试后根据结果选用代码写法。
2.mono .net 4.0环境要比.net 3.5环境运行效率更高。
(特意拿出以前的测试项目升级到了.net 4.0运行环境再次测试,效率全部有提升,分别提升了8%~25%)

测试代码:

using UnityEngine;
using UnityEditor;
using System.Diagnostics;

/// <summary>
/// 执行时间测试
/// ZhangYu 2019-04-13
/// </summary>
public class TimeTest : MonoBehaviour {

    private static Stopwatch watch;

    private void Start() {
        Execute();
    }

    [MenuItem("CONTEXT/TimeTest/执行")]
    private static void Execute() {
        watch = new Stopwatch();

        // 数据长度
        int total = 100000000;
        int[] array = new int[total];
        for (int i = 0; i < total; i++) {
            array[i] = i + 1;
        }

        // For1
        watch.Reset();
        watch.Start();
        ForTest1(array);
        watch.Stop();
        string msgFor1 = string.Format("For1: {0}s", watch.Elapsed);

        // For2
        watch.Reset();
        watch.Start();
        ForTest2(array);
        watch.Stop();
        string msgFor2 = string.Format("For2: {0}s", watch.Elapsed);

        // Foreach
        watch.Reset();
        watch.Start();
        ForeachTest(array);
        watch.Stop();
        string msgForeach = string.Format("Foreach: {0}s", watch.Elapsed);

        print(msgFor1);
        print(msgFor2);
        print(msgForeach);
    }

    public static void ForTest1(int[] array) {
        for (int i = 0; i < array.Length; i++) {
            int v = array[i] + 1;
        }
    }

    public static void ForTest2(int[] array) {
        int length = array.Length;
        for (int i = 0; i < length; i++) {
            int v = array[i] + 1;
        }
    }

    public static void ForeachTest(int[] array) {
        foreach (int item in array) {
            int v = item + 1;
        }
    }
}

执行方式
在mono .net 3.5 运行环境下结果:
setting 3.5
.net 3.5

测试结果:
排除运行环境的误差,for循环和foreach循环在数十次的测试结果中,for更快一点,For2方法优化了一下length的取值,似乎定义了length比直接使用array.Length更慢了一点儿,还是直接使用array.length吧。

在mono .net 4.0 运行环境下结果:
setting 4.0
.net 4.0

测试结果:
foreach比for更快。


冰封百度
233 声望43 粉丝

Unity游戏程序员一枚。生命不息,学习不止。