我有一个小结构,并且发现复制单个成员要比一次复制结构快得多。这有充分的理由吗?
我的节目:
// 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;
为了测量纳秒范围内的时间,我进行了数百万次的分配:
uint uStart = GetTickCount();
for (int nLoop=0; nLoop<10000000; nLoop++)
{
// Do something...
}
uint uElapsed = (GetTickCount() - uStart);
结果与启用和禁用优化大致一致...复制这个小结构的个别成员的速度大约是其两倍。同样的结果是否适用于C / C ++?
答案 0 :(得分: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);
}
}
我的时间如下所示:
struct fields
Debug/Debug 2,245 1,908
Debug/No 2,238 1,919
Release/Debug 287 294
Release/No 281 275
这是在Visual Studio 2015中。该程序编译为任何CPU,并在64位计算机上运行。
Debug / Debug意味着在附加调试器的情况下运行调试版本(即按F5运行程序)。 Debug / No表示没有调试的调试构建运行(即Ctrl + F5)。当然,发布意味着发布版本。
这告诉我的是,在发布模式下,一次复制结构或复制单个字段几乎没有区别。在这里显示的最坏情况下,它超过10亿次迭代的时间为6毫秒。
您的问题的答案:“复制个人成员比整个结构更快?”似乎是“在调试模式下,是的。”