1

我试图检查拳击和不拳击的表现。这是一个代码:

public struct p1
{
    int x, y;
    public p1(int i)
    {
        x = y = i;
    }

}
public class MainClass
{
    public static void Main()
    {
        var al = new List<object>();
        var l = new List<p1>();
        var sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 1000; i++)
        {
            al.Add(new p1(i));
        }
        p1 b;
        for (int i = 0; i < 1000; i++)
        {
            b = (p1)al[i];
        }
        Console.WriteLine(sw.ElapsedTicks);

        var time = sw.ElapsedTicks;

        for (int i = 0; i < 1000; i++)
        {
            l.Add(new p1(i));
        }
        p1 v;
        for (int i = 0; i < 1000; i++)
        {
            v = l[i];
        }
        var t = sw.ElapsedTicks - time;
        Console.WriteLine(t);
        Console.ReadKey();
    }
}

但是对象列表比 p1 列表工作得更快。为什么?
1139 9256
1044 6909

4

2 回答 2

3

我怀疑这可能是由很多事情引起的。

首先,您应该始终将这样的计时放入一个循环中,并在同一进程中多次运行它们。JIT 开销将在第一次运行时发生,并且可以支配您的时间。这会扭曲结果。(通常,你会想要完全忽略第一次运行......)

此外,请确保您在发布版本中运行它,在 Visual Studio 测试主机之外运行。(不要按 F5 - 使用 Ctrl+F5 或从 VS 外部运行。)否则,测试主机将禁用大多数优化并显着减慢您的结果。

例如,尝试以下操作:

public static void Main()
{
    for (int run = 0; run < 4; ++run)
    {
        if (run != 0)
        {
            // Ignore first run
            Console.WriteLine("Run {0}", run);
        }
        var al = new List<object>();
        var l = new List<p1>();
        var sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 1000; i++)
        {
            al.Add(new p1(i));
        }
        p1 b;
        for (int i = 0; i < 1000; i++)
        {
            b = (p1)al[i];
        }
        sw.Stop();
        if (run != 0)
        {
            // Ignore first run
            Console.WriteLine("With boxing: {0}", sw.ElapsedTicks);
        }

        sw.Reset();
        sw.Start();
        for (int i = 0; i < 1000; i++)
        {
            l.Add(new p1(i));
        }
        p1 v;
        for (int i = 0; i < 1000; i++)
        {
            v = l[i];
        }
        sw.Stop();
        if (run != 0)
        {
            // Ignore first run
            Console.WriteLine("Without boxing: {0}", sw.ElapsedTicks);
        }
    }
    Console.ReadKey();
}

在我的系统上,通过忽略第一次运行(JIT 问题),并在发行版的 VS 测试主机之外运行,我得到:

Run 1
With boxing: 99
Without boxing: 61
Run 2
With boxing: 92
Without boxing: 56
Run 3
With boxing: 97
Without boxing: 54

对于通用的非盒装版本,这显然要好得多。

鉴于您的结果中的数字非常大 - 我怀疑这个测试是在 VS 中以调试模式运行的......

于 2011-01-06T19:13:05.793 回答
0

结构是按值而不是引用传递的。当您自动装箱时,我相信它将通过引用传递。所以它在第二个循环中被复制了多次。

于 2011-01-06T19:18:03.607 回答