почему так медленно?
От: CodeMonkey  
Дата: 07.06.19 17:02
Оценка:
  Скрытый текст
    class Program
    {
        static void Main(string[] args)
        {
            var num = 10_000_000;

            {
                var watch = Stopwatch.StartNew();

                var data = new TestClass[num];
                for (var i = 0; i < data.Length; i++)
                {
                    data[i] = new TestClass
                    {
                        Number0 = 10,
                        Number1 = 20,
                    };
                }

                watch.Stop();
                Console.WriteLine(watch.Elapsed.TotalSeconds);
            }

            {
                var watch = Stopwatch.StartNew();

                var data = new TestStruct[num];
                for (var i = 0; i < data.Length; i++)
                {
                    data[i].Number0 = 10;
                    data[i].Number1 = 20;
                }

                watch.Stop();
                Console.WriteLine(watch.Elapsed.TotalSeconds);
            }
        }

        struct TestStruct
        {
            public long Number0;
            public long Number1;
            public long Temp0;
            public long Temp1;
            public long Temp2;
            public long Temp3;
            public long Temp4;
            public long Temp5;
            public long Temp6;
            public long Temp7;
        }

        class TestClass
        {
            public long Number0;
            public long Number1;
            public long Temp0;
            public long Temp1;
            public long Temp2;
            public long Temp3;
            public long Temp4;
            public long Temp5;
            public long Temp6;
            public long Temp7;
        }
    }


Получается:

1.6395053
0.2299897

Откуда здесь разница аж в 8 раз?
Re: почему так медленно?
От: vorona  
Дата: 07.06.19 17:46
Оценка:
Здравствуйте, CodeMonkey, Вы писали:

ref struct
Re[2]: почему так медленно?
От: CodeMonkey  
Дата: 07.06.19 17:50
Оценка:
Здравствуйте, vorona, Вы писали:

V>ref struct


Ты точно уверен, что посмотрел код и понял, что он делает?
Re[3]: почему так медленно?
От: vorona  
Дата: 07.06.19 20:04
Оценка: 5 (1)
Здравствуйте, CodeMonkey, Вы писали:

GC.TryStartNoGCRegion(10_000_000 * 128, true);
var watch = Stopwatch.StartNew();

var data = new TestClass[num];
for (var i = 0; i < data.Length; i++)
{
    data[i] = new TestClass
    {
        Number0 = 10,
        Number1 = 20,
    };
}

watch.Stop();
Console.WriteLine(watch.Elapsed.TotalSeconds);
GC.EndNoGCRegion();


У меня получилось
0,4047961
0,2600024
Re[4]: почему так медленно?
От: CodeMonkey  
Дата: 07.06.19 20:29
Оценка:
Здравствуйте, vorona, Вы писали:

V>У меня получилось

V>0,4047961
V>0,2600024

А у меня получилось

System.ArgumentOutOfRangeException: 'totalSize is too large. For more information about setting the maximum size, see "Latency Modes" in http://go.microsoft.com/fwlink/?LinkId=522706
Parameter name: totalSize'

Re: почему так медленно?
От: ylem  
Дата: 07.06.19 22:28
Оценка: :)
Профайлер вам в помощь.
Но если гадать, ставлю на очевидное -- выделение места по экземпляр ссылочного типа.
Еще, вероятно, запись в поле элемента массива быстрее, чем в объект. Оно вроде бы делается через "ссылку на экзепляр" ссылочного типа.
Отредактировано 07.06.2019 22:34 ylem . Предыдущая версия .
Re[2]: почему так медленно?
От: CodeMonkey  
Дата: 07.06.19 23:03
Оценка:
Здравствуйте, ylem, Вы писали:

Y>Профайлер вам в помощь.


Профайлеру низкоуровневые вещи вообще неведомы.

Y>Но если гадать, ставлю на очевидное -- выделение места по экземпляр ссылочного типа.


А чего там делать то так долго? Обнулить нужное количество памяти, поинкрементить указатель на свободное место. Всё.
Re[3]: почему так медленно?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 08.06.19 09:01
Оценка:
Здравствуйте, CodeMonkey, Вы писали:

CM>А чего там делать то так долго? Обнулить нужное количество памяти, поинкрементить указатель на свободное место. Всё.

Не все. У тебя 10_000_000 * 80 байт. Вспоминаем про виртуальную память, так как реальная память выделяется по мере необходимости.

Второй прогон по идее должен быть быстрее после сборки мусора, если GC оставит память зарезервированной.
и солнце б утром не вставало, когда бы не было меня
Re: почему так медленно?
От: okon  
Дата: 08.06.19 09:19
Оценка:
CM>Откуда здесь разница аж в 8 раз?

Помоему очевидно, в первом цикле есть постоянное дергание new что достаточно дорогая операция по сравнению с доступом по индексу и копированием long, во втором нету.
Второй момент структуры оптимизируются под стек насколько мне известно и даже если структура будет во втором цикле не явно создаваться, то пара процессорных операций со стеком аля push будет дешевле, чем целая логика менеджера памяти который работает с кучей. Не утверждаю что все именно так, не проверял.
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Re[5]: почему так медленно?
От: vorona  
Дата: 08.06.19 10:54
Оценка:
Здравствуйте, CodeMonkey, Вы писали:

CM>

CM>System.ArgumentOutOfRangeException: 'totalSize is too large. For more information about setting the maximum size, see "Latency Modes" in http://go.microsoft.com/fwlink/?LinkId=522706
CM>Parameter name: totalSize'


В файле проекта нужно написать

<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>

и сделать ребилд
Re[2]: почему так медленно?
От: Sharov Россия  
Дата: 08.06.19 12:51
Оценка:
Здравствуйте, okon, Вы писали:

O>Второй момент структуры оптимизируются под стек насколько мне известно и даже если структура будет во втором цикле не явно создаваться, то пара процессорных операций со стеком аля push будет дешевле, чем целая логика менеджера памяти который работает с кучей. Не утверждаю что все именно так, не проверял.


Массив все равно будет в куче.
Кодом людям нужно помогать!
Re[3]: почему так медленно?
От: ylem  
Дата: 08.06.19 17:04
Оценка:
CM>А чего там делать то так долго? Обнулить нужное количество памяти, поинкрементить указатель на свободное место. Всё.
Это не долго. Но в первом варианте не надо делать _вообще_ ничего.
Re[4]: почему так медленно?
От: CodeMonkey  
Дата: 08.06.19 17:18
Оценка:
Здравствуйте, ylem, Вы писали:

Y>Это не долго.


А ты на цифры посмотри. Вариант с классами в разы медленнее, чем со структурами.
Re[6]: почему так медленно?
От: CodeMonkey  
Дата: 08.06.19 17:27
Оценка:
Здравствуйте, vorona, Вы писали:

V>В файле проекта нужно написать

V>

V><PropertyGroup>
V> <ServerGarbageCollection>true</ServerGarbageCollection>
V></PropertyGroup>


А, так это Core. Важное уточнение.
Получается

0.4799392
0.1881155

даже без вызова TryStartNoGCRegion
Re[4]: почему так медленно?
От: CodeMonkey  
Дата: 08.06.19 17:29
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Второй прогон по идее должен быть быстрее после сборки мусора, если GC оставит память зарезервированной.


Ни фига подобного, получается даже медленнее.
Re[5]: почему так медленно?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 08.06.19 18:48
Оценка:
Здравствуйте, CodeMonkey, Вы писали:

CM>Здравствуйте, Serginio1, Вы писали:


S>> Второй прогон по идее должен быть быстрее после сборки мусора, если GC оставит память зарезервированной.


CM>Ни фига подобного, получается даже медленнее.


Тогда проблема со сборкой мусора как правильно указал vorona GC.TryStartNoGCRegion(10_000_000 * 128, true);
и солнце б утром не вставало, когда бы не было меня
Re[6]: почему так медленно?
От: CodeMonkey  
Дата: 08.06.19 19:17
Оценка:
Здравствуйте, Serginio1, Вы писали:

S> Тогда проблема со сборкой мусора как правильно указал vorona GC.TryStartNoGCRegion(10_000_000 * 128, true);


Вполне возможно, но почему?
Re[7]: почему так медленно?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 08.06.19 19:24
Оценка:
Здравствуйте, CodeMonkey, Вы писали:

CM>Здравствуйте, Serginio1, Вы писали:


S>> Тогда проблема со сборкой мусора как правильно указал vorona GC.TryStartNoGCRegion(10_000_000 * 128, true);


CM>Вполне возможно, но почему?


https://docs.microsoft.com/ru-ru/dotnet/standard/garbage-collection/fundamentals
Условия для сборки мусора

Сборка мусора возникает при выполнении одного из следующих условий:

Память, используемая объектами, выделенными в управляемой куче, превышает допустимый порог. Этот порог непрерывно корректируется во время выполнения процесса.

Там же про Эфемерные поколения и сегменты

и еще про параллелизмом

Для компьютера с одним процессором всегда используется сборка мусора рабочей станции, независимо от значения элемента <gcServer>. Если задана сборка мусора сервера, среда CLR использует сборку мусора рабочей станции с выключенным параллелизмом.

и солнце б утром не вставало, когда бы не было меня
Re[8]: почему так медленно?
От: CodeMonkey  
Дата: 08.06.19 20:11
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Условия для сборки мусора


S>

S>Сборка мусора возникает при выполнении одного из следующих условий:

S>Память, используемая объектами, выделенными в управляемой куче, превышает допустимый порог. Этот порог непрерывно корректируется во время выполнения процесса.

S>Там же про Эфемерные поколения и сегменты

S> и еще про параллелизмом


S>

S>Для компьютера с одним процессором всегда используется сборка мусора рабочей станции, независимо от значения элемента <gcServer>. Если задана сборка мусора сервера, среда CLR использует сборку мусора рабочей станции с выключенным параллелизмом.



И что? Где тут написано, почему оно так тормозит?
Re[9]: почему так медленно?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 08.06.19 20:42
Оценка:
Здравствуйте, CodeMonkey, Вы писали:



CM>И что? Где тут написано, почему оно так тормозит?


Ну тормозит из-за сборки мусора. И написано когда сборка возникает.
и солнце б утром не вставало, когда бы не было меня
Отредактировано 08.06.2019 20:52 Serginio1 . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.