Почему 16 байтов являются рекомендуемым размером для структуры в C#?

Я прочитал книгу Cwalina (рекомендации на разработке и дизайне приложений.NET).

Он говорит, что хорошая разработанная структура должна составить меньше чем 16 байтов в размере (в целях производительности).

Почему точно это?

И (более важный) у меня может быть большая структура с той же эффективностью, если я выполняю свою.NET 3.5 (скоро, чтобы быть.NET 4.0), 64-разрядное приложение на  Core i7 в соответствии с Windows 7 x64 (это ограничение ЦП / базирующаяся ОС)?

Только для выделения снова - мне нужно как эффективная структура, поскольку это возможно. Я пытаюсь сохранить его на стеке все время. Приложение является в большой степени многопоточным и работает на интервалах подмиллисекунды, и текущий размер структуры составляет 64 байта.

34
задан Peter Mortensen 7 May 2017 в 17:31
поделиться

5 ответов

Только вы знаете, как ваши структуры используются в вашей программе. Но как бы то ни было, вы всегда можете проверить это на себе. Например, если он часто передается другим функциям, вас может прояснить следующее:

class MainClass
{
    static void Main()
    {
        Struct64 s1 = new Struct64();
        Class64 c1 = new Class64();
        DoStuff(s1);
        DoStuff(c1);
        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 10000; i++)
        {
            s1 = DoStuff(s1);
        }
        sw.Stop();
        Console.WriteLine("Struct {0}", sw.ElapsedTicks);
        sw.Reset();

        sw.Start();
        for (int i = 0; i < 10000; i++)
        {
            c1 = DoStuff(c1);
        }
        sw.Stop();
        Console.WriteLine("Class {0}", sw.ElapsedTicks);
        sw.Reset();

        Console.ReadLine();
    }
}

with:

public class Class64
{
    public long l1;
    public long l2;
    public long l3;
    public long l4;
    public long l5;
    public long l6;
    public long l7;
    public long l8;
}
public struct Struct64
{
    public long l1;
    public long l2;
    public long l3;
    public long l4;
    public long l5;
    public long l6;
    public long l7;
    public long l8;
}

Попробуйте такие вещи с репрезентативными структурами / классами и посмотрите, какие результаты вы получите. (На моей машине, в приведенном выше тесте, класс кажется примерно в 3 раза быстрее)

9
ответ дан 27 November 2019 в 16:59
поделиться

Вы неправильно цитируете книгу (по крайней мере, 2-е издание). Джеффри Рихтер утверждает, что типы значений могут быть больше 16 байтов, если:

Вы не собираетесь передавать их другим методам или копировать их в класс коллекции и из него.

Дополнительно Эрик Ганнерсон добавляет (относительно ограничения в 16 байт)

Используйте это руководство как триггер для дополнительных исследований.

Это просто неправда, что структура «должна быть меньше 16 байт в размере». Все зависит от использования.

Если вы создаете структуру, а также потребляете ее и беспокоитесь о производительности, используйте профилировщик, сравнивая структуру с классом, чтобы увидеть, что лучше всего подходит для вас.

21
ответ дан 27 November 2019 в 16:59
поделиться

Одна из вещей, которую я узнал, когда делал Программирование на языке ассемблера заключалось в выравнивании структур (и других данных) по 8- или 16-байтовым границам (на самом деле в MASM для этого есть команда препроцессора). Причина этого - значительно более быстрый доступ к памяти при хранении или перемещении вещей в памяти. Сохранение ваших структур размером менее 16 байт гарантирует, что это выравнивание памяти может быть выполнено успешно, потому что ничто не будет пересекать границы выравнивания.

Однако я ожидал, что подобные вещи будут в значительной степени скрыты от вас при использовании .NET framework. Если бы ваши структуры были больше 16 байт, я бы ожидал, что фреймворк (или JIT-компилятор) выровняет ваши данные по 32-байтовым границам и так далее. Было бы интересно увидеть некоторые подтверждения комментариев в этих книгах и увидеть, какова разница в скорости.

3
ответ дан 27 November 2019 в 16:59
поделиться
  • Более крупная структура не так эффективна, но тогда .... если у вас ЕСТЬ больше данных, они у вас есть. Нет смысла говорить об эффективности.

  • 64 байта должно быть в порядке.

  • Основная причина, возможно, в операциях копирования ... которые замедляются IIRC, если структура больше. И это надо довольно много копировать.

Обычно я бы посоветовал использовать здесь класс;) Но без знания содержимого структуры это немного сложно.

4
ответ дан 27 November 2019 в 16:59
поделиться

Я думаю, что еще один ключевой момент заключается в том, что если у вас есть список с миллионом структур, это все равно только одно выделение памяти в куче, а список с миллион классов в нем будет иметь около миллиона отдельных объектов кучи. Загрузка сборки мусора в обоих случаях совершенно разная. С этой точки зрения структура может выйти вперед.

1
ответ дан 27 November 2019 в 16:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: