Я работаю над некоторыми приложениями, которые требуют очень низкой задержки и многократно загружают память и проводят некоторые проверки того, как, например, выделение списка ad-hoc против предварительного распределения и очистки списка. Я ожидал, что тестовые прогоны предопределяют память для выполнения намного быстрее, но, к моему удивлению, они на самом деле немного медленнее (когда я пропустил тест на 10 минут, средняя средняя - около 400 мс)..NET pre-allocating memory vs ad-hoc allocation
Вот тестовый код, который я использовал:
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();
}
}
Теперь, что действительно интересно, я бегу системного монитора бок о бок и увидел следующую картину, которая выглядит, как я ожидал:
Green = Gen 0 коллекции
Синий = Выделено байт/сек
Red =% времени в GC
Консольное приложение ниже показывает тест автономной работы для # 1 и # 2
Итак, мой вопрос: почему тест # 1 быстрее, чем # 2?
Очевидно, что я бы предпочел бы статистику перфтонов теста № 2 в моем приложении, поскольку в основном нет давления памяти, нет коллекций GC и т. Д., Но # 1 кажется немного быстрее?
Имеет ли List.Clear() столько накладных расходов?
Спасибо,
Том
EDIT Я сделал еще один тест, с теми же установками, но работает приложение с сервером GC позволил теперь # 2 становится немного быстрее
Спасибо, за ваш ответ это имеет смысл. Какой вариант вы бы выбрали, хотя в сценарии производства, который очень похож? Теперь, что очень интересно, когда я запускаю одно и то же приложение с включенным GC сервера, # 2 на самом деле становится быстрее. Я обновил сообщение и приложил скриншот – TJF
@Tom: Режим сервера ускоряет общую пропускную способность за счет более высокой задержки. Что лучше, зависит от вас. При этом я обычно использую # 1 в своей производственной среде - код чище, и он, как правило, лучше работает в целом. –