C#性能因内存而异

mez*_*hic 8 .net c# memory performance memory-management

希望这是一个有效的帖子,它是C#问题和硬件的结合.

我正在对我们的服务器进行基准测试,因为我们发现了定量库的性能问题(用C#编写).我用一些简单的C#代码模拟了相同的性能问题 - 执行非常繁重的内存使用.

下面的代码是一个从线程池产生的函数,最多32个线程(因为我们的服务器有4个CPU x 8个核心).

这一切都在.Net 3.5上

问题是我们的性能差异很大.我运行以下功能1000次.代码运行所需的平均时间可能是3.5秒,但最快的只有1.2秒,而最慢的将是7秒 - 完全相同的功能!

我已经根据时间绘制了内存使用情况,并且似乎与GC没有任何关联.

我注意到的一件事是,当在一个线程中运行时,时间是相同的,没有疯狂的偏差.我还测试了CPU绑定算法,时序也相同.这让我们想知道内存总线是否无法应对.

我想知道这可能是另一个.net或C#问题,还是与我们的硬件有关?如果我使用过C++或Java,这会是同样的经历吗?我们使用4x Intel x7550和32GB内存.一般来说这个问题有什么办法吗?

Stopwatch watch = new Stopwatch();
watch.Start();
List<byte> list1 = new List<byte>();
List<byte> list2 = new List<byte>();
List<byte> list3 = new List<byte>();


int Size1 = 10000000;
int Size2 = 2 * Size1;
int Size3 = Size1;

for (int i = 0; i < Size1; i++)
{
    list1.Add(57);
}

for (int i = 0; i < Size2; i = i + 2)
{
    list2.Add(56);
}

for (int i = 0; i < Size3; i++)
{
    byte temp = list1.ElementAt(i);
    byte temp2 = list2.ElementAt(i);
    list3.Add(temp);
    list2[i] = temp;
    list1[i] = temp2;
}
watch.Stop();
Run Code Online (Sandbox Code Playgroud)

(代码只是为了强调内存)

我会包含线程池代码,但我们使用了非标准的线程池库.

编辑:我已将"size1"减少到100000,基本上没有使用太多内存,我仍然会得到很多抖动.这表明它不是传输的内存量,而是记忆的频率?

小智 0

List内部使用数组来存储。我相信每次达到列表中可用空间的限制时,它都会尝试将数组的大小加倍。

当您进入循环时,随着列表的增长,它需要越来越大的连续内存块来分配新数组。通过一个线程,这非常容易。对于 2 个以上的线程,您正在争夺大块的连续内存。当数组变得更大并且连续内存更难找到时,它会随机触发 GC。