比整个结构更快地复制个人成员?

Ala*_*inD 5 c#

我有一个小结构,并发现复制单个成员要比一次复制结构快得多.有这么好的理由吗?

我的节目:

// Some random structure
private struct PackStats
{
    public int nGoodPacks, nBadPacks, nTotalPacks;
}

// ...
PackStats stats1 = new PackStats();
PackStats stats2 = new PackStats();

// Set some random statistics
stats1.nGoodPacks = 55;
stats1.nBadPacks = 3;
stats1.nTotalPacks = (stats1.nGoodPacks + stats1.nBadPacks);

// Now assign stats2 from stats1

// This single line consumes ~190ns...
stats2 = stats1;

// ...but these three lines consume ~100ns (in total)
stats2.nGoodPacks = stats1.nGoodPacks;
stats2.nBadPacks = stats1.nBadPacks;
stats2.nTotalPacks = stats1.nTotalPacks;
Run Code Online (Sandbox Code Playgroud)

为了测量纳秒范围内的时间,我做了数百万次的分配:

uint uStart = GetTickCount();
for (int nLoop=0; nLoop<10000000; nLoop++)
{
    // Do something...
}
uint uElapsed = (GetTickCount() - uStart);
Run Code Online (Sandbox Code Playgroud)

结果与启用和禁用优化大致一致...复制这个小结构的个别成员的速度大约是其两倍.同样的结果会适用于C/C++吗?

Jim*_*hel 3

您的时间似乎是用于调试构建。我用这段代码做了同样的测试:

    private void DoIt()
    {
        const int numReps = 1000000000;
        PackStats stats1 = new PackStats();
        PackStats stats2 = new PackStats();

        stats1.a = 55;
        stats1.b = 3;
        stats1.c = stats1.a + stats1.b;

        for (var i = 0; i < 2; ++i)
        {
            var sw1 = Stopwatch.StartNew();
            for (var j = 0; j < numReps; ++j)
            {
                stats2 = stats1;
            }
            sw1.Stop();
            Console.WriteLine("Copy struct = {0:N0} ms", sw1.ElapsedMilliseconds);

            sw1.Restart();
            for (var j = 0; j < numReps; ++j)
            {
                stats2.a = stats1.a;
                stats2.b = stats1.b;
                stats2.c = stats1.c;
            }
            sw1.Stop();
            Console.WriteLine("Copy fields = {0:N0} ms", sw1.ElapsedMilliseconds);
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的时间安排如下:

                struct       fields
Debug/Debug     2,245        1,908
Debug/No        2,238        1,919
Release/Debug   287          294
Release/No      281          275
Run Code Online (Sandbox Code Playgroud)

这是使用 Visual Studio 2015 进行的。该程序被编译为任何 CPU,并在 64 位计算机上运行。

调试/调试意味着附加调试器的调试构建运行(即按 F5 运行程序)。调试/否表示调试构建运行而不进行调试(即 Ctrl+F5)。当然,发布意味着发布版本。

这告诉我的是,在发布模式下,一次复制全部结构或复制各个字段之间几乎没有区别。在此处显示的最坏情况下,十亿次迭代需要 6 毫秒。

您的问题的答案:“复制单个成员比复制整个结构更快?” 似乎是“在调试模式下,是的”。