我正在研究一些需要非常低的延迟并推送大量内存的应用程序,并正在对一些应用程序进行测试。分配一个列表ad-hoc与预分配和清除列表执行。 我期待测试运行时预分配内存的执行速度要快得多,但令我惊讶的是它们实际上稍慢(当我让测试运行10分钟时,平均差异大约为400ms)。.NET预分配内存vs临时分配
下面是测试代码,我用:
class Program
{
private static byte[] buffer = new byte[50];
private static List<byte[]> preAlloctedList = new List<byte[]>(500);
static void Main(string[] args)
{
for (int k = 0; k < 5; k++)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
List<byte[]> list = new List<byte[]>(300);
for (int j = 0; j < 300; j++)
{
list.Add(buffer);
}
}
sw.Stop();
Console.WriteLine("#1: " + sw.Elapsed);
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
for (int j = 0; j < 300; j++)
{
preAlloctedList.Add(buffer);
}
preAlloctedList.Clear();
}
sw.Stop();
Console.WriteLine("#2: " + sw.Elapsed);
}
Console.ReadLine();
}
}
现在,什么是真正有趣的,我跑并排性能监视器侧,看到下面的图案看起来像我的预期:
绿色=第0级集合
蓝色=分配的字节/秒
红色=%在GC时间
下面的控制台应用程序显示#1和试验运行时#2
所以,我的问题是,为什么测试#1比#2更快?
显然,我宁愿在我的应用程序中测试#2的perfmon统计数据,因为基本上没有内存压力,没有GC集合等,但#1似乎稍快一点?
List.Clear()会带来多大的开销吗?
感谢,
汤姆
编辑 我做了另外一个测试,用相同的设置,但运行与服务器GC的应用启用,目前#2变稍快
非常感谢您的回复。你会选择哪一个选项,但在非常相似的生产场景中?现在,有趣的是,当我启用服务器GC运行相同的应用程序时,#2实际上变得更快。我更新了这篇文章,并附上截图 – TJF 2010-10-20 19:37:29
@Tom:服务器模式以更高的延迟为代价提高了整体吞吐量。哪个更好取决于你。话虽如此,我通常只在我的生产环境中使用#1 - 代码更干净,而且它的整体性能更好。 – 2010-10-20 20:01:21