JIT-компилятор создает специальный код для копирования структур, которые меньше определенного порога, и несколько более медленную конструкцию общего назначения для больших. Я предположил бы, что, когда этот совет был написан, порог был 16 байтов, но в сегодняшней 32-битной структуре это, кажется, 24 байта; может быть больше для 64-битного кода.
Как уже было сказано, стоимость создания любого объекта класса размера существенно больше, чем стоимость копирования структуры, содержащей те же данные. Если код создает объект класса с полями размером 32 байта, а затем передает или иным образом копирует ссылку на этот объект 1000 раз, экономия времени при копировании 1000 ссылок на объекты вместо необходимости копировать 1000 32-байтовых структур, вероятно, перевесит стоимость создание объекта класса. Однако если экземпляр объекта будет отменен после того, как ссылка будет скопирована только дважды, стоимость создания объекта, вероятно, значительно превысит стоимость копирования 32-байтовой структуры в два раза.
Обратите также внимание, что во многих случаях можно избежать передачи структур по значению или иным образом избыточного их копирования, если кто-либо попытается это сделать. Например, для передачи любого размера структуры в качестве параметра ref
методу требуется только передача адреса из одного машинного слова (4 или 8 байтов). Поскольку в .net отсутствует какая-либо концепция const ref
, таким образом могут быть переданы только доступные для записи поля или переменные, а коллекции, встроенные в .net - кроме System.Array
- не предоставляют средств для доступа к членам с помощью ref
. Однако если вы хотите использовать массивы или пользовательские коллекции, даже огромные (100 байт или более) структуры могут быть обработаны очень эффективно. Во многих случаях преимущество в производительности при использовании структуры, а не неизменяемого класса может возрасти с размером инкапсулированных данных.